line in a JLabel that disappear when adding to a new frame

Hi,

I have the main frame (SampleFrame), where I put a JPanel with CardLayout, I want when I click on a button, a new JPanel (SamplePanel) is shown.

The problem is this new JPanel shows a picture (a line in a JLabel), the poblem is the picture does not appear...

The code is the following:

package sample;

//Main Class

publicclass Main{

publicstaticvoid main(String[] args){

java.awt.EventQueue.invokeLater(new Runnable(){

publicvoid run(){

new SampleFrame().setVisible(true);

}

});

}

}

//SampleFrame

package sample;

import javax.swing.JPanel;

import javax.swing.*;

import java.awt.*;

publicclass SampleFrameextends javax.swing.JFrame{

private SamplePanel samplePanel;

privateboolean flag;

/** Creates new form SampleFrame */

public SampleFrame(){

initComponents();

flag=false;

samplePanel =new SamplePanel();

jPanel1.add(samplePanel,"sample");

}

/** This method is called from within the constructor to

* initialize the form.

* WARNING: Do NOT modify this code. The content of this method is

* always regenerated by the Form Editor.

*/

// <editor-fold defaultstate="collapsed" desc=" Generated Code ">

privatevoid initComponents(){

jPanel1 =new javax.swing.JPanel();

jButton1 =new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jPanel1.setLayout(new java.awt.CardLayout());

jButton1.setText("OK");

jButton1.addActionListener(new java.awt.event.ActionListener(){

publicvoid actionPerformed(java.awt.event.ActionEvent evt){

jButton1ActionPerformed(evt);

}

});

org.jdesktop.layout.GroupLayout layout =new org.jdesktop.layout.GroupLayout(getContentPane());

getContentPane().setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

.add(layout.createSequentialGroup()

.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

.add(layout.createSequentialGroup()

.addContainerGap()

.add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 189, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))

.add(layout.createSequentialGroup()

.add(81, 81, 81)

.add(jButton1)))

.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))

);

layout.setVerticalGroup(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

.add(layout.createSequentialGroup()

.addContainerGap()

.add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 182, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)

.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 19, Short.MAX_VALUE)

.add(jButton1)

.addContainerGap())

);

pack();

}// </editor-fold>

privatevoid jButton1ActionPerformed(java.awt.event.ActionEvent evt){

// TODO add your handling code here:

CardLayout cl = (CardLayout)(jPanel1.getLayout());

cl.show(jPanel1,"sample");

flag=true;

/* this.setVisible(false);

this.setVisible(true);*/

}

publicvoid paint(Graphics g)

{

super.paint(g);

if(flag)samplePanel.ReDraw();

}

publicvoid printAll(Graphics g)

{

super.printAll( g);

if(flag)samplePanel.ReDraw();

}

// Variables declaration - do not modify

private javax.swing.JButton jButton1;

private javax.swing.JPanel jPanel1;

// End of variables declaration

}

//SamplePanel

package sample;

import javax.swing.*;

import java.awt.event.*;

import java.awt.*;

publicclass SamplePanelextends javax.swing.JPanel{

/** Creates new form SamplePanel */

public SamplePanel(){

initComponents();

}

/** This method is called from within the constructor to

* initialize the form.

* WARNING: Do NOT modify this code. The content of this method is

* always regenerated by the Form Editor.

*/

// <editor-fold defaultstate="collapsed" desc=" Generated Code ">

privatevoid initComponents(){

jLabel1 =new javax.swing.JLabel();

org.jdesktop.layout.GroupLayout layout =new org.jdesktop.layout.GroupLayout(this);

this.setLayout(layout);

layout.setHorizontalGroup(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

.add(layout.createSequentialGroup()

.addContainerGap()

.add(jLabel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 150, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)

.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))

);

layout.setVerticalGroup(

layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)

.add(layout.createSequentialGroup()

.addContainerGap()

.add(jLabel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 150, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)

.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))

);

}// </editor-fold>

publicvoid paint(Graphics g)

{

super.paint(g);

ReDraw();

}

publicvoid printAll(Graphics g)

{

super.printAll( g);

ReDraw();

}

publicvoid ReDraw()

{

Graphics g = jLabel1.getGraphics();

g.drawLine(0,0,100,100);

}

// Variables declaration - do not modify

private javax.swing.JLabel jLabel1;

// End of variables declaration

}

I have discovered that with the comment lines in SampleFrame (method jButton1ActionPerformed):

/* this.setVisible(false);

this.setVisible(true);*/

works properly, but I dont like this way...

Can anyone helps me? Thanks ;)

[9685 byte] By [naskara] at [2007-11-26 13:41:46]
# 1

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class SF extends JFrame {

private JPanel jPanel1;

public SF() {

// Initialize components.

jPanel1 = new JPanel(new CardLayout());

jPanel1.add(new SP(10,10,100,100,Color.red), "sample 1");

jPanel1.add(new SP(50,150,200,50,Color.blue), "sample 2");

JButton jButton1 = new JButton("OK");

jButton1.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent evt) {

CardLayout cl = (CardLayout)(jPanel1.getLayout());

cl.next(jPanel1);

}

});

JPanel south = new JPanel();

south.add(jButton1);

// Configuration and assemble JFrame.

setDefaultCloseOperation(EXIT_ON_CLOSE);

add(jPanel1);// Default center section.

add(south, "Last");

pack();

setLocation(200,200);

setVisible(true);

}

public static void main(String[] args) {

new SF();

}

}

class SP extends JPanel {

private int x1;

private int y1;

private int x2;

private int y2;

private Color color;

public SP(int x1, int y1, int x2, int y2, Color c) {

this.x1 = x1;

this.y1 = y1;

this.x2 = x2;

this.y2 = y2;

color = c;

}

protected void paintComponent(Graphics g) {

super.paintComponent(g);

g.setColor(color);

g.drawLine(x1, y1, x2, y2);

}

// You may need this if you are going to call pack

// on the top-level container of this component.

// Return whatever dimensions you want this to be

// displayed with by the parent. Those that respect

// preferredSize will honor it. Otherwise, it may be

// shown at its default size of (10, 10) or even (0, 0).

public Dimension getPreferredSize() {

return new Dimension(300, 200);

}

}

crwooda at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 2
Thanks for you Reply ;), but what I want is to paint on a label which is contained on a panel...In your code, SP must have a JLabel where you paint the line.I tried myself with your code but I have had the same problem than at first...Some idea?
naskara at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 3

Try changing your implementation of SP to this:

class SP extends JPanel {

private int x1;

private int y1;

private int x2;

private int y2;

private Color color;

public SP(int x1, int y1, int x2, int y2, Color c) {

this.x1 = x1;

this.y1 = y1;

this.x2 = x2;

this.y2 = y2;

color = c;

setLayout(new BorderLayout());

add(new DrawingLabel());

}

private class DrawingLabel extends JLabel {

protected void paintComponent(Graphics g) {

g.setColor(color);

g.drawLine(x1, y1, x2, y2);

}

}

public Dimension getPreferredSize() {

return new Dimension(300, 200);

}

}

crwooda at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 4

That磗 what I want ;).

Bur i prefer painting in the SP, i tried with:

class SP extends JPanel {

private int x1;

private int y1;

private int x2;

private int y2;

private Color color;

private JLabel label;

public SP(int x1, int y1, int x2, int y2, Color c) {

this.x1 = x1;

this.y1 = y1;

this.x2 = x2;

this.y2 = y2;

color = c;

setLayout(new BorderLayout());

label =new JLabel();

add(label);

}

protected void paintComponent(Graphics g) {

super.paintComponent(g);

label.getGraphics().setColor(color);

label.getGraphics().drawLine(x1, y1, x2, y2);

}

public Dimension getPreferredSize() {

return new Dimension(300, 200);

}

}

but doesnt work...

naskara at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 5

The changes you posted last work okay (j2se 1.5). The JLabel is non–opaque and allows the

colored lines on the panel surface to show through. The question is why do you want to

draw on the JPanel and place a JLabel on top of the drawing? Usually when we do graphics

we do all the drawing on a JPanel and do not add any components (except maybe a Border) to

it. Then use the JPanel as a component with other components. Adding components to a

JPanel with graphics on it covers up the graphics. Can you say what you are trying to do?

Maybe there is an easier/more productive/less tricky way.

If you must add a JLabel with graphics you could try to place it in say the north or south

sections of a BorderLayout or use a GridBagLayout. It is usually easier to draw the text

in with the graphics and avoid problems with other components, layout managers, resizing

behavior, etc.

crwooda at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 6

But with that code the app need to receive a pain event to show the line..

I want that the lines appear directly...

I have a main frame(mainFrame), and I want to reuse an old frame (oldFrame) which has some drawings, these drawings are on several labels of the oldFrame.

So thats why I am trying with a panel with a drawing label..

Very thanks for your replies crwood ;)

naskara at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 7

the app need to receive a pain event to show the line..

You can have a boolean in SP (member variable) that can control whether or not something

is drawn in paintComponent. This boolean value can be changed by another class in

your app, for example, with user input through a JCheckBox.

reuse an old frame (oldFrame) which has some drawings, these drawings are on several

labels of the oldFrame

I'm confused.

crwooda at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 8

For example, imagine you have a class like SP, with a label (and you have a draw which is drawed on the label).

You have to develop a new class -> SF, and you realised that you need to have the same funcionality than SP, so you decide to have a JPanel with CardLayout (panel) in your SF, so you do that:

panel.add(new SP().getContentPane(),"panel1");

the problem is when yo show that panel with:

CardLayout cl = (CardLayout)(panel.getLayout());

cl.show(panel, "panel1");

I get the same problem that with your code..the draw in the label its not shown directly...

Can you modify your code to get this?

I hope I have explained myself in a clarity way now.

naskara at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 9
any idea?
naskara at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 10

I hope I have explained myself in a clarity way now.

I'm still not sure I understand.

I have a main frame(mainFrame), and I want to reuse an old frame (oldFrame) which has

some drawings, these drawings are on several labels of the oldFrame

panel.add(new SP().getContentPane(),"panel1");

Okay, you're taking the content pane, a Container, from a top–level container (you

mentioned a frame, "oldFrame"). And this container contains some JLabels which have lines

drawn in them. You want to add this container to a card in a Cardlayout. Okay, so far so

good.

Now you want to be able to toggle the visibility of these lines? In other words have the

JLabel drawings, the lines drawn in each JLabel, to be drawn or not drawn controlled by

event code. Is this correct? So the user can press a button and the line(s) in a JLabel

will become visible after one press and then invisible with the next button press. Is this

correct?

I'm sure you could rig something up that would do this, like remove the JLabels from this

other frame and add them into a JDialog or new JFrame. Or maybe even make copies of them.

But there are problems with this. First of all it most unusual to have more than one

top–level container in an app; for other/extra windows we usually use a JDialog. Depending

on what your goals are there may be an easier way to go about this. So I have been

reluctant to say or do more since the basic premise feels shakey, ie, outside the

boundries of good practice. So I am waiting for more information along the lines of what

is it you want to do, why do you want to mount the existing labels on a new top–level

container. I would like some more perspective to be able to offer a considered opinion,

suggestion or solution.

crwooda at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 11

Hi again crwood!!

Okay, you're taking the content pane, a Container, from a top杔evel container (you mentioned a frame, "oldFrame"). And this container contains some JLabels which have lines drawn in them. You want to add this container to a card in a Cardlayout. Okay, so far so good.

That磗 exactly what I want ;).

So (using your code):

I have the panel:

class SP extends JPanel {

private int x1;

private int y1;

private int x2;

private int y2;

private Color color;

private JLabel label;

public SP(int x1, int y1, int x2, int y2, Color c) {

this.x1 = x1;

this.y1 = y1;

this.x2 = x2;

this.y2 = y2;

color = c;

setLayout(new BorderLayout());

label =new JLabel();

add(label);

}

protected void paintComponent(Graphics g) {

super.paintComponent(g);

label.getGraphics().setColor(color);

label.getGraphics().drawLine(x1, y1, x2, y2);

}

public Dimension getPreferredSize() {

return new Dimension(300, 200);

}

}

And the main frame:

public class SF extends JFrame {

private JPanel jPanel1;

public SF() {

// Initialize components.

jPanel1 = new JPanel(new CardLayout());

jPanel1.add(new SP(10,10,100,100,Color.red), "sample 1");

jPanel1.add(new SP(50,150,200,50,Color.blue), "sample 2");

JButton jButton1 = new JButton("OK");

jButton1.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent evt) {

CardLayout cl = (CardLayout)(jPanel1.getLayout());

cl.next(jPanel1);

}

});

JPanel south = new JPanel();

south.add(jButton1);

// Configuration and assemble JFrame.

setDefaultCloseOperation(EXIT_ON_CLOSE);

add(jPanel1);// Default center section.

add(south, "Last");

pack();

setLocation(200,200);

setVisible(true);

}

public static void main(String[] args) {

new SF();

}

}

The problem is I cant see the black line...

(I am able to see it by moving the window until hide part of it)

naskara at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 12

I copied, pasted, changed the names of the classes, compiled and ran the two classes you

last posted. When the app was launched I saw the label "Hello World" and a red line above

it. Pressing the "OK" button shows the same label and a blue line to the right of the

label. The app seems to be working okay. Have you checked to makes sure that there are no

old class files in your classpath? Maybe change the names to avoid confusion with previous

work.

crwooda at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...
# 13

This is a very strange thing... Have you tried the code where the lines are painted on the label?

I am still getting the same results...

Thats what I can see when I execute the app:

http://img507.imageshack.us/my.php?image=snap1dk3.png

And this when I hide part of the window:

http://img505.imageshack.us/my.php?image=snap2qe1.png

naskara at 2007-7-7 23:58:43 > top of Java-index,Security,Cryptography...