JFrame: Can't launch new window - java

I'm trying to learn Java and JFrames. I put together this simple app where the Main class launches the MainGui class. MainGui will contain a bunch of buttons that each does something different (right now it only has the canadaFlagButton). I have no problem getting the window for MainGui to open with the button I created.
However, when I click the canadaFlagButton, it is supposed to launch a new window but instead, nothing happens.
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MainGui extends JFrame implements ActionListener {
JButton canadaFlagButton;
MainGui() {
canadaFlagButton = new JButton("Canada Flag");
canadaFlagButton.setBounds(100, 100, 200, 50);
canadaFlagButton.setFocusable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 600);
this.setLayout(null);
this.add(canadaFlagButton);
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==canadaFlagButton) {
CanadaFlag window1 = new CanadaFlag();
}
}
}
//Can I draw the Canadian flag?
This is the CanadaFlag class:
import javax.swing.*;
import java.awt.*;
public class CanadaFlag extends JFrame {
CanadaFlag() {
//creating label for maple leaf
JLabel leafLabel = new JLabel();
ImageIcon leaf = new ImageIcon("mapleleaf.png");
leafLabel.setIcon(leaf);
leafLabel.setVerticalAlignment(JLabel.CENTER);
leafLabel.setHorizontalAlignment(JLabel.CENTER);
JPanel redLeftPanel = new JPanel();
redLeftPanel.setBackground(Color.red);
redLeftPanel.setBounds(0, 0, 400, 1000);
JPanel redRightPanel = new JPanel();
redRightPanel.setBackground(Color.red);
redRightPanel.setBounds(1000, 0, 400, 1000);
JPanel whiteMiddlePanel = new JPanel();
whiteMiddlePanel.setBackground(Color.white);
whiteMiddlePanel.setBounds(400, 0, 600, 1000);
whiteMiddlePanel.setLayout(new BorderLayout());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
this.setSize(1400, 1000);
this.setVisible(true);
this.add(redLeftPanel);
this.add(redRightPanel);
this.add(whiteMiddlePanel);
whiteMiddlePanel.add(leafLabel);
}
}

An application should only have a single main JFrame. If you need other windows then you would typically use a JDialog.
Swing was designed to be used with layout manager. If you are trying to learn Swing then check out the Swing tutorial on Layout Managers for more information and working example.
it is supposed to launch a new window but instead, nothing happens
You never add the ActionListener to the button.
canadaFlagButton.addActionListener( this );
The tutorial also has a section on How to Use Buttons that contains a working example. I suggest you keep a reference to the tutorial for examples of all Swing basics.

Related

How do I create a new JFrame?

I'm a complete beginner to Java, and I'm finding some answers a bit too technical for me (even the most basic tutorials seem to give me syntax errors when I run the code). How, in really simple terms do I add a JButton to a JFrame? I've got as far as:
import javax.swing.JButton;
import javax.swing.JFrame;
public class JF {
public static void main(String[] args) {
JFrame myFrame = new JFrame();
/*some pretty basic code to initialize the JFrame i.e.
myFrame.setSize(300, 200);
This is as far as I got
*/
}
}
I would seriously appreciate some help!
Creating a new JFrame
The way to create a new instance of a JFrame is pretty simple.
All you have to do is:
JFrame myFrame = new JFrame("Frame Title");
But now the Window is hidden, to see the Window you must use the setVisible(boolean flag) method. Like this:
myFrame.setVisible(true);
Adding Components
There are many ways to add a Component to a JFrame.
The simplest way is:
myFrame.getContentPane().add(new JButton());//in this case we are adding a Button
This will just add a new Component that will fill the JFrame().
If you do not want the Component to fill the screen then you should either make the ContentPane of the JFrame a new custom Container
myFrame.getContentPane() = new JPanel();
OR add a custom Container to the ContentPane and add everything else there.
JPanel mainPanel = new JPanel();
myFrame.getContentPane().add(mainPanel);
If you do not want to write the myFrame.getContentPane() every time then you could just keep an instance of the ContentPane.
JPanel pane = myFrame.getContentPane();
Basic Properties
The most basic properties of the JFrame are:
Size
Location
CloseOperation
You can either set the Size by using:
myFrame.setSize(new Dimension(300, 200));//in pixels
Or packing the JFrame after adding all the components (Better practice).
myFrame.pack();
You can set the Location by using:
myFrame.setLocation(new Point(100, 100));// starting from top left corner
Finally you can set the CloseOperation (what happens when X is pressed) by
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
There are 4 different actions that you can choose from:
DO_NOTHING_ON_CLOSE //Nothing happens
HIDE_ON_CLOSE //setVisible(false)
DISPOSE_ON_CLOSE //Closes JFrame, Application still runs
EXIT_ON_CLOSE //Closes Application
Using Event Dispatch Thread
You should initialize all GUI in Event Dispatch Thread, you can do this by simply doing:
class GUI implements Runnable {
public static void main(String[] args) {
EventQueue.invokeLater(new GUI());
}
#Override
public void run() {
JFrame myFrame = new JFrame("Frame Title");
myFrame.setLocation(new Point(100, 100));
myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
myFrame.getContentPane().add(mainPanel);
mainPanel.add(new JButton("Button Text"), BorderLayout.CENTER);
myFrame.pack();
myFrame.setLocationByPlatform(true);
myFrame.setVisible(true);
}
}
//I hope this will help
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
public class JF extends JFrame
{
private JButton myButton;//Here you begin by declaring the button
public JF()//Here you create you constructor. Constructors are used for initializing variable
{
myButton = new JButton();//We initialize our variable
myButton.setText("My Button"); //And give it a name
JPanel panel1 = new JPanel();//In java panels are useful for holding content
panel1.add(myButton);//Here you put your button in the panel
add(panel1);//This make the panel visible together with its contents
setSize(300,400);//Set the size of your window
setVisible(true);//Make your window visible
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
JFrame frame = new JF();
frame.setTitle("My First Button");
frame.setLocation(400,200);
}
}

Jbutton positioning inside a tabbed pane

I am currently working on making a digital school planner and want to use multiple JButtons inside a JTabbedPane. But I am currently having a problem where even one button takes up the whole pane and would like a solution to this.
I have created a test program that mirrors how i am coding my main program:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTabbedPane;
public class tabTest extends JFrame {
private static final long serialVersionUID = 5101892517858668104L;
private JFrame frame;
private int WIDTH = 450;
private int HEIGHT = 600;
private JTabbedPane tab;
public tabTest() {
frame = new JFrame();
// frame.setUndecorated(true);
/****************************************************
* Set up frame
*****************************************************/
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH, HEIGHT);
frame.setLocation(50, 50);
frame.getContentPane().setBackground(Color.GRAY);
frame.getContentPane().setLayout(null);
/******************************************************
* Set up Tabbed pane and buttons
******************************************************/
tab = new JTabbedPane();
tab.setBounds(20, 50, 400, 500);
tab.setBackground(Color.white);
tab.setFocusable(false);
JButton tabButton1 = new JButton("test");
tab.addTab("Week 1", tabButton1);
tab.addTab("Week 2", null);
tab.addTab("Week 3", null);
tab.addTab("Week 4", null);
frame.getContentPane().add(tab);
frame.setVisible(true);
}
public static void main(String[] args) {
new tabTest();
}
}
i have tried using BorderLayout.POSITION and it chucked up error after error any alternate solution would be great :)
Your tabbedPane can only hold one "object". If you add a button, your pane is full. However you can add a container with more room to the pane. For example a JPanel. The JPanel can now hold as many "objects" as you want and can use it's own LayoutManager.
JPanel moreButtons = new JPanel();
moreButtons.add(new JButton("test1"));
moreButtons.add(new JButton("test2"));
moreButtons.add(new JButton("test3"));
moreButtons.add(new JButton("test4"));
tab.addTab("Week 1", moreButtons);
Also you crete and initialize your whole GUI inside the constructor. It might be cleaner to define a second methode like initializeGUI() to seperate the creation of the object and the initilazation of your GUI. Also you should seperate the GUI-thread and the Main-thread, by using invokeLater
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Gui g = new Gui();
g.initalizeGUI();
Gui.setVisible(true);
}
});
}
There is no need to extend JFrame and to create a seperate JFrame inside your JFrame. Remove the extends JFrame or the creation of your JFrame inside the class. You can access the JFrame mehtodes from inside your extended class.
public class MyFrame extends JFrame {
public MyFrame () {
/**
* Set up frame
*/
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT);
setLocation(50, 50);
getContentPane().setBackground(Color.GRAY);
getContentPane().setLayout(null);
}
}
Add another container like JPanel inside your JTabbedPane like this:
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout()); // you can change layout according to your need.
p.add(tabButton1);
tab.addTab("Week 1", panel);
tab.addTab("Week 2", null);
tab.addTab("Week 3", null);
tab.addTab("Week 4", null);
Add all your components to the JPanel that you want to show on the tabs.

JAVA - Can't add Text Field and Button to container

I'm trying to do a little program that use some buttons and text field.
I was able to create window with JPanel but don't have idea how to add button and text field
The code I'm using is:
public UI() {
sprites = new HashMap();
// spriteCache = stage.getSpriteCache();
JFrame okno = new JFrame ("VoLTE Script");
setBounds(0,0,SZEROKOSC,WYSOKOSC);
JPanel panel = (JPanel)okno.getContentPane();
panel.setLayout (null);
panel.add(this);
okno.setBounds(0,0,800,600);
okno.setVisible(true);
JTextField pole = new JTextField(10);
JButton przycisk = new JButton("teasda");
przycisk.setPreferredSize(new Dimension(300, 350));
przycisk.setLayout(new BorderLayout());
panel.add(przycisk);
przycisk.setVisible(true);
pole.setBounds (300,300,200,200);
pole.setLayout(null);
pole.setVisible(true);
panel.add(pole);
okno.addWindowListener(new WindowAdapter(){
public void windowClosing (WindowEvent e){
System.exit(0);
}
});
okno.setResizable(false);
createBufferStrategy(2);
strategia=getBufferStrategy();
requestFocus();
// addKeyListener(this);
// addMouseListener(this);
}
You need to use the layout properly, when using border layout you need to tell it which border to use (, BorderLayout.NORTH or something), check out the tutorials at oracles page.
P.S. Think of how your naming your fields etc. Naming something "przycisk" just gives me a reason not to read the code further.
Thank You for help and sorry for Polish names(fixed already).
I was able to add Text Area with scroll.
Looks like problem was in panel.add(this); putted before button and text field.
From my understanding if panel.add(this) is set before panel.add(pole); then panel.add(this) is set in front and pole is added but not seen.
Below my actual working code:
...
public UI() {
sprites = new HashMap();
// spriteCache = stage.getSpriteCache();
JFrame okno = new JFrame ("VoLTE Script");
setBounds(0,0,WIDTH,HEIGHT);
JPanel panel = (JPanel)okno.getContentPane();
panel.setLayout (null);
okno.setBounds(0,0,800,600);
okno.setVisible(true);
JTextArea pole = new JTextArea();
pole.setLayout(null);
pole.setLineWrap(true);
//pole.setBackground(Color.BLACK);
pole.setEditable(false);
JScrollPane scroll = new JScrollPane(pole);
scroll.setBounds(25,250,500,300);
scroll.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
panel.add(scroll);
panel.add(this);
okno.addWindowListener(new WindowAdapter(){
public void windowClosing (WindowEvent e){
System.exit(0);
}
});
okno.setResizable(false);
createBufferStrategy(2);
strategia=getBufferStrategy();
requestFocus();
// addKeyListener(this);
addMouseListener(this);
}
...
This code is from this site: Example of Java GUI
//Imports are listed in full to show what's being used
//could just import javax.swing.* and java.awt.* etc..
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComboBox;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class GuiApp1 {
//Note: Typically the main method will be in a
//separate class. As this is a simple one class
//example it's all in the one class.
public static void main(String[] args) {
new GuiApp1();
}
public GuiApp1()
{
JFrame guiFrame = new JFrame();
//make sure the program exits when the frame closes
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Example GUI");
guiFrame.setSize(300,250);
//This will center the JFrame in the middle of the screen
guiFrame.setLocationRelativeTo(null);
//Options for the JComboBox
String[] fruitOptions = {"Apple", "Apricot", "Banana"
,"Cherry", "Date", "Kiwi", "Orange", "Pear", "Strawberry"};
//Options for the JList
String[] vegOptions = {"Asparagus", "Beans", "Broccoli", "Cabbage"
, "Carrot", "Celery", "Cucumber", "Leek", "Mushroom"
, "Pepper", "Radish", "Shallot", "Spinach", "Swede"
, "Turnip"};
//The first JPanel contains a JLabel and JCombobox
final JPanel comboPanel = new JPanel();
JLabel comboLbl = new JLabel("Fruits:");
JComboBox fruits = new JComboBox(fruitOptions);
comboPanel.add(comboLbl);
comboPanel.add(fruits);
//Create the second JPanel. Add a JLabel and JList and
//make use the JPanel is not visible.
final JPanel listPanel = new JPanel();
listPanel.setVisible(false);
JLabel listLbl = new JLabel("Vegetables:");
JList vegs = new JList(vegOptions);
vegs.setLayoutOrientation(JList.HORIZONTAL_WRAP);
listPanel.add(listLbl);
listPanel.add(vegs);
JButton vegFruitBut = new JButton( "Fruit or Veg");
//The ActionListener class is used to handle the
//event that happens when the user clicks the button.
//As there is not a lot that needs to happen we can
//define an anonymous inner class to make the code simpler.
vegFruitBut.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
//When the fruit of veg button is pressed
//the setVisible value of the listPanel and
//comboPanel is switched from true to
//value or vice versa.
listPanel.setVisible(!listPanel.isVisible());
comboPanel.setVisible(!comboPanel.isVisible());
}
});
//The JFrame uses the BorderLayout layout manager.
//Put the two JPanels and JButton in different areas.
guiFrame.add(comboPanel, BorderLayout.NORTH);
guiFrame.add(listPanel, BorderLayout.CENTER);
guiFrame.add(vegFruitBut,BorderLayout.SOUTH);
//make sure the JFrame is visible
guiFrame.setVisible(true);
}
}
For the future i will recommend you to use the extends JFrame so you can only write a gui like this without initialize a JFrame:
public class CalculatorGUI extends JFrame {
public CalculatorGUI() {
setTitle("Calculator");
setBounds(300, 300, 220, 200);
}}
I suggest you check out a couple of tutorials about how to create a Java Gui or sth.

Java Swing. Opening a new JPanel from a JButton and making the buttons pretty

I am trying to build a little program that has a main GUI with 2 buttons. One button closes the program, the other I want to open a new JPanel that will have text fields etc.
I would like to be able to make the buttons so they look like normal application buttons I guess, nice and square, equal size etc. etc., I am not sure how to do this though.
Also, I am unsure how to open a new JFrame from a button click.
GUI Code:
package practice;
public class UserInterface extends JFrame {
private JButton openReportSelection = new JButton("Open new Window");
private JButton closeButton = new JButton("Close Program");
private JButton getCloseButton() {
return closeButton;
}
private JButton getOpenReportSelection() {
return openReportSelection;
}
public UserInterface() {
mainInterface();
}
private void mainInterface() {
setTitle("Program Information Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel centerPanel = new JPanel(new GridLayout(0, 3));
centerPanel.add(openReportSelection);
centerPanel.add(closeButton);
getCloseButton().addActionListener(new Listener());
add(centerPanel, BorderLayout.CENTER);
setSize(1000, 200);
setVisible(true);
}
private void addReportPanel() {
JPanel reportPanel = createNewPanel();
getContentPane().add(reportPanel, BorderLayout.CENTER);
}
private JPanel createNewPanel() {
JPanel localJPanel = new JPanel();
localJPanel.setLayout(new FlowLayout());
return localJPanel;
}
}
ActionListener Class code:
package practice;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Listener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
}
EDIT: I think opening a new JPanel would be the way to go rather than a JFrame. What would be the best way to do this from a Jbutton click?
Start by using a different layout manager, FlowLayout or GridBagLayout might work better
JPanel centerPanel = new JPanel(new FlowLayout());
centerPanel.add(openReportSelection);
centerPanel.add(closeButton);
These layouts will honour the preferred sizes of your buttons
As for opening another window, well, you've already create one, so the process is pretty much the same. Having said that, you might consider having a look at The Use of Multiple JFrames: Good or Bad Practice? before you commit yourself to far.
A better approach might be to use a JMenuBar and JMenuItems to act as the "open" and "exit" actions. Take a look at How to Use Menus then you could use a CardLayout to switch between views instead, for example
From a pure design perspective (I know it's only practice, but perfect practice makes perfect), I wouldn't extend anything from JFrame and instead would rely on building your main GUIs around something like JPanel instead.
This affords you the flexibility to decide how to use these components, as you could add them to frames, applets or other components...
If you want your buttons to have the native Look and Feel (L&F), add the following to your program:
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
Instead of opening another JFrame, you'll want to instead use a JDialog, typically with modality set.
In Java, you can only extend one class and therefore you should consider carefully whether it is appropriate or not to extend another class. You could ask yourself, "Am I actually extending the functionality of JFrame?" If the answer is no, then you actually want to use an instance variable.
Below is an example program from the above recommendations:
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class MyApplication {
private JFrame myframe; // instance variable of a JFrame
private JDialog mydialog;
public MyApplication() {
super();
myframe = new JFrame(); // instantiation
myframe.setSize(new Dimension(400, 75));
myframe.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
JButton btnNewWindow = new JButton("Open New Window");
btnNewWindow.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mydialog = new JDialog();
mydialog.setSize(new Dimension(400,100));
mydialog.setTitle("I got you! You can't click on your JFrame now!");
mydialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); // prevent user from doing something else
mydialog.setVisible(true);
}
});
myframe.getContentPane().add(btnNewWindow);
JButton btnCloseProgram = new JButton("Close Program :(");
btnCloseProgram.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
myframe.dispose();
}
});
myframe.getContentPane().add(btnCloseProgram);
myframe.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MyApplication();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
I am not sure from your question what do wou want to do. Do you want to open a new JFrame or do you want to add a JPanel to the existing frame.
To open a new JFrame using a button, create an instance of the JFrame in the actionPerformed method of the button. In your case it would look similar to this:
openReportSelection.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JFrame frame = new JFrame();
// Do something with the frame
}
}
});
You're probably looking up to create and open a new JFrame. For this purpose, first you need to instantiate an object from JFrame Class. As an example, Let's instantiate a new JFrame with specific boundries.
JFrame testFrame = new testFrame();
verificationFrame.setBounds(400, 100, 250, 250);
Then you need to create your components like JButtons, Jlabels and so on, and next you should add them to your new testFrame object.
for example, let's create a Jlabel and add it testFrame:
JLabel testLbl = new JLabel("Ok");
testLbl.setBounds(319, 49, 200, 30);
testFrame.getContentPane().add(testLbl);
Now let's suppose you have a Jbutton which is named "jbutton" and by clicking it, a new JFrame object will be created and the Jlabel component will be added to it:
jButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JFrame testFrame = new testFrame();
verificationFrame.setBounds(400, 100, 250, 250);
Label testLbl = new JLabel("Ok");
testLbl.setBounds(319, 49, 200, 30);
testFrame.getContentPane().add(testLbl);
}}});

JLayeredPane not drawing

Good day,
Hopefully this is a quick kill question. I am writing an application that uses JPanels and JLayeredPane inside a JFrame. On the initial start of my application, one of the panels does not show up until my mouse moves over the area where the panel should be. I even call the validate and repaint methods, but I am still able to display both panels together. Any suggestions? Thank you.
Here is my JFrame class (which has the main method)
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
public class Application extends JFrame
{
public Application()
{
this.setSize(500,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
JLayeredPane lp = new JLayeredPane();
lp.setBounds(0,0,500,500);
this.setLayeredPane(lp);
Mypanel p1 = new Mypanel();
Mypanel2 p2 = new Mypanel2();
this.getLayeredPane().add(p1,0);
this.getLayeredPane().add(p2,1);
this.validate();
this.repaint();
this.validate();
}
public static void main(String[] args)
{
Application app = new Application();
}
}
Here is one of my panel classes
import javax.swing.JButton;
import javax.swing.JPanel;
public class Mypanel extends JPanel
{
public JButton button;
public Mypanel()
{
this.setLayout(null);
this.setBounds(0, 0, 500, 500);
JButton b = new JButton("Hello");
b.setBounds(20,20,300,300);
this.add(b);
}
}
And finally my last panel class
import javax.swing.JButton;
import javax.swing.JPanel;
public class Mypanel2 extends JPanel
{
public JButton button;
public Mypanel2()
{
this.setLayout(null);
this.setBounds(0, 0, 500, 500);
JButton b = new JButton("SUP");
b.setBounds(20,10,200,200);
this.add(b);
this.repaint();
this.validate();
this.repaint();
}
}
First off, in a valid program only JComponent repaints itself. If at some point you find that calling c.repaint() from your controller code fixes some problem, you have neglected basic contracts that at the core of swing framework. And this is never a good idea. So removing all those repaint and validate calls is a good start. Next important thing is understanding how lightweight swing components go about painting their children. There are 2 modes: optimized and not optimized. The first one is only applicable when siblings don't overlap eachother in the container. If they do and optimized painting is on, you are going to get all sorts of weird behavior when those components repaint themselves(like when you hover mouse pointer over them). All lightweight components can handle overlapping children through setComponentZOrder() . JLayeredPane only introduces the concept of a layer as a means of controlling zorder in a more flexible way. It tries to be smart about what mode to choose to paint its children but, sadly there are subtleties to how this works. so this code would do what you need:
Mypanel p1 = new Mypanel();
Mypanel2 p2 = new Mypanel2();
getLayeredPane().setLayer(p1,0);
getLayeredPane().setLayer(p2,1);
getLayeredPane().add(p1);
getLayeredPane().add(p2);
and this wouldn't:
Mypanel p1 = new Mypanel();
Mypanel2 p2 = new Mypanel2();
getLayeredPane().add(p1);
getLayeredPane().add(p2);
getLayeredPane().setLayer(p1,0);
getLayeredPane().setLayer(p2,1);
the trick is to call setLayer before you add children to the container so that JLayeredPane would turn off optimized painting.
BTW I couldn't help but wonder why JLayeredPane? If you need switching programmatically between different layouts maybe JTabbedPane is your answer anyways
JLayeredPane lp = new JLayeredPane();
JPanel d = new JPanel();
d.setVisible(true);
d.setBounds(10, 10, 556, 386);
lp.add(d, new Integer(0), 0);

Categories

Resources