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);
}
}
# 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?
# 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);
}
}
# 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...
# 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.
# 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 ;)
# 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.
# 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.
# 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.
# 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)
# 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.
# 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