Referencing(?) problem with windows in GUI - java

--EDIT--
I have got a welcome window consisting of two JLabels. It has a link to a timer counting from 3 to 0. After that time, a new window, "UsedBefore", containing JLabel and radio buttons should automatically appear in the place of the previous one. When I run the "Launcher", the first window shows up with counter displaying 3,2,1,0 and then nothing happens.
I think the problem lies in poor referencing, but I'm not sure. I've got "Launcher" class:
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Welcome window = new Welcome();
window.setVisible(true);
}
});
} // end main
Where I launch the "Welcome" window:
public Welcome() {
init();
}
public void init() {
// here I'm adding stuff to the window and then I have:
setLayout(cardLayout);
add(big, "1welcome");
// UsedBefore.MakeUsedBeforeWindow(); // ???
new MyTimer(this).start();
} // end init
this goes to MyTimer which does the countdown and:
welcome.showNextWindow(); // private Welcome welcome;
we go back to the "Welcome" class:
public void showNextWindow() {
cardLayout.next(this);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("My Frame");
frame.getContentPane().add(new Welcome());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(550, 450);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
and finally the "UsedBefore" class:
public UsedBefore() {
super(new BorderLayout());
init();
}
public void MakeUsedBeforeWindow() {
String q = "Have you used GUI before?";
JPanel area = new JPanel(new BorderLayout());
add(area, "2usedBefore?");
area.setBackground(Color.white);
JLabel textLabel = new JLabel("<html><div style=\"text-align: center;\">"
+ q + "</html>", SwingConstants.CENTER);
textLabel.setForeground(Color.green);
Font font = new Font("SansSerif", Font.PLAIN, 30);
textLabel.setFont(font);
textLabel.setBorder(new EmptyBorder(0, 0, 250, 0)); //top, left, bottom, right
area.add(textLabel, SwingConstants.CENTER);
add(area, "2usedBefore?");
}
with its main:
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("RadioButtons");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane - not sure how to do it
// JComponent newContentPane = new UsedBefore();
// newContentPane.setOpaque(true); //content panes must be opaque
// frame.setContentPane(newContentPane);
// frame.getContentPane().add(new UsedBefore());
//Display the window.
frame.setSize(550, 450);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
That's quite a journey. Sorry for a lot of code, I hope the path is clear. Once I've got 1->2->3 links right, I should be able to do the rest of them, so any help is appreciated. Thank you.

I suggest a slightly different approach. Why not building JPanel instead of Windows and adding/removing these JPanel at the desire time.
Ex (here welcome panel is shown first with its decreasing counter and when the counter reach 0, other panel is shown):
public class T extends JFrame {
private int couterValue = 3;
private JPanel welcome;
private JLabel counter;
private JPanel other;
private Timer timer;
public T() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
buildWelcomePanel();
buildOtherPanel();
add(welcome);
setSize(550, 450);
setLocationRelativeTo(null);
setVisible(true);
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
if (couterValue == 0) {
timer.cancel();
// Switch the panels as the counter reached 0
remove(welcome);
add(other);
validate();
} else {
counter.setText(couterValue + ""); // Update the UI counter
couterValue--;
}
}
}, 0, 1000);
}
private void buildWelcomePanel() {
welcome = new JPanel();
counter = new JLabel();
welcome.add(counter);
}
private void buildOtherPanel() {
other = new JPanel();
JLabel otherStuff = new JLabel("Anything else ...");
other.add(otherStuff);
}
public static void main(String[] args) {
new T();
}
}

Related

How to add components to the frame?

I am new to Swing programming. And I m trying to develop a desktop application.
First all I need to create a login window, which should not be draggable and its position must be in center of the screen.
So by learning , I have created a window by the following code:
import com.sun.awt.AWTUtilities;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Newframe {
private JLabel label;
JFrame frame;
JButton btn;
Newframe(){
prepareGUI();
}
public static void main(String arg[]) {
Newframe n=new Newframe();
}
public void prepareGUI(){
frame=new JFrame();
frame.setUndecorated(true);
frame.setSize(300, 300);
frame.setVisible(true);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);
}
}
Now, I want to add components (e.g textfields, labels, buttons, etc...) to this created frame.
I m trying to add the components to the frame by initialize the components and add them to the frame ( by this frame.add(jbutton)) , but components are not going to add to the created frame...
Can any one help me for this?
frame.getContentPane().add(component)
Note this may vary depending on the layout you use.
Also, it'd be better to put the UI in the Event Dispatch Thread, with this:
public static void main(String arg[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Newframe n=new Newframe();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
You can use below code to add component to the frame and to center the frame you can use frame.setLocationRelativeTo(null);.
public class Newframe {
private JLabel label;
private JTextField txt;
JFrame frame;
JButton btn;
Newframe() {
prepareGUI();
}
public static void main(String arg[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
Newframe n = new Newframe();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void prepareGUI() {
frame = new JFrame();
frame.setLayout(null);
frame.setSize(300, 300);
frame.setUndecorated(true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
// frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);
label = new JLabel("Name");
label.setBounds(10, 10, 100, 20);
frame.add(label);
txt = new JTextField();
txt.setBounds(50, 10, 100, 20);
frame.add(txt);
btn = new JButton("OK");
btn.setBounds(40, 40, 80, 20);
frame.add(btn);
}
}

Bringing JInternalFrame on top of other JPanel

I have 2 JPanel, named as "panelMenu" and "panelTable". Both of them are added into JDesktopPane, named as "desktop". I have put a button in "panelMenu" and when it is clicked, it will bring up a JInternalFrame.
Both of the panels are set side by side in the "desktop"...here comes the problem...when I clicked on the button...the JInternalFrame will show up but it is initially at the back of the "panelTable"...how can I bring the JInternalFrame to be always on top of any other components?
//Adding panels into desktop
panelMenu.setBackground(Color.yellow);
panelMenu.setBounds(0,0,200,800);
panelMenu.setLayout(null);
panelTable.setBackground(Color.gray);
panelTable.setBounds(250,50,700,700);
panelTable.setLayout(null);
desktop.setLayout(null);
desktop.setSize(width, height);
desktop.setBackground(Color.gray);
desktop.add(panelMenu);
desktop.add(panelTable);
this.add(desktop);
How about using JOptionPane.showInternalXXXDialog(...):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class InternalMessageDialogTest {
private final JDesktopPane desktop = new JDesktopPane();
public JComponent makeUI() {
JButton button = new JButton(new AbstractAction("open") {
#Override public void actionPerformed(ActionEvent e) {
JOptionPane.showInternalMessageDialog(
desktop, "information", "modal",
JOptionPane.INFORMATION_MESSAGE);
}
});
JPanel panelMenu = new JPanel();
panelMenu.setBackground(Color.YELLOW);
panelMenu.add(button);
panelMenu.setBounds(0, 0, 100, 100);
JInternalFrame panelTable = new JInternalFrame("Table");
panelTable.add(new JScrollPane(new JTable(30, 3)));
panelTable.setBounds(100, 0, 200, 100);
desktop.add(panelMenu);
desktop.add(panelTable);
panelMenu.setVisible(true);
panelTable.setVisible(true);
JPanel p = new JPanel(new BorderLayout());
p.add(desktop);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new InternalMessageDialogTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
Following code will help you
//yourDesktopPane
//panelMenu
//panelTable
//buttonMenu
//buttonTable
private void buttonMenuMouseClicked(java.awt.event.MouseEvent evt) {
panelMenu obj = new panelMenu ();
BasicInternalFrameUI bi = (BasicInternalFrameUI) obj.getUI();
bi.setNorthPane(null);
obj.setBounds(0, 0, 1220, 700);//your desired values
obj.setVisible(true);
yourDesktopPane.add(obj);
obj.toFront();
}
private void buttonTableMouseClicked(java.awt.event.MouseEvent evt) {
panelTableobj = new panelTable();
BasicInternalFrameUI bi = (BasicInternalFrameUI) obj.getUI();
bi.setNorthPane(null);
obj.setBounds(0, 0, 1220, 700);//your desired values
obj.setVisible(true);
yourDesktopPane.add(obj);
obj.toFront();
}

Swing Component not displaying on the frame

I don't understand why the RackBuilder object I added to the frame does not get displayed.
The code runs and the frame gets generated. I expect to see a panel with 42 rows, each row containing a JLabel "test". Is there something incorrect/missing from my constructor?
public class RackBuilderTool extends JPanel{
public RackBuilderTool() {
super(new GridLayout(42, 0));
for (int i = 0; i < 42; i++) {
add(new JLabel("test"));
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Rack Builder Tool");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
RackBuilderTool rackBuilder = new RackBuilderTool();
rackBuilder.setOpaque(true);
frame.setContentPane(rackBuilder);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Thanks!
import javax.swing.*;
import java.awt.*;
public class RackBuilderTool extends JPanel{
public RackBuilderTool() {
super(new GridLayout(42, 0));
for (int i = 0; i < 42; i++) {
add(new JLabel("test"));
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("Rack Builder Tool");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
RackBuilderTool rackBuilder = new RackBuilderTool();
rackBuilder.setOpaque(true);
frame.setContentPane(rackBuilder);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
now it will show you 42 rows of your label.
Realized that the "run" button on Netbeans IDE is to run the entire project. As a result it was running another java file under the same project.
Once I right clicked on the java file I wanted to compile and clicked run it worked.
Thanks everyone for the help.

What is the proper way to swap out an existing JPanel in a JFrame with another?

I'm building a program that requires swapping out the current, visible JPanel with another. Unfortunately there seems to be multiple to go about this and all of my attempts have ended in failure. I can successfully get the first JPanel to appear in my JFrame, but swapping JPanels results in a blank JFrame.
My Main JFrame:
public class ShellFrame {
static CardLayout cl = new CardLayout(); //handles panel switching
static JFrame frame; //init swing on EDT
static MainMenu mm;
static Panel2 p2;
static Panel3 p3;
public static void main(String[] args) {
initFrame();
}
public static void initFrame() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame = new JFrame();
frame.setDefaultCloseOperation(3);
frame.setLayout(cl);
mm = new MainMenu();
pp = new PlacementPanel();
//first panel added to frame will always show first
frame.add(mm, "MainMenu");
frame.pack(); //sizes frame to fit the panel being shown
frame.setVisible(true);
}
});
}
public static void switchPanel(String name) {
cl.show(frame.getContentPane(), name);
frame.pack();
}
public static void updatePanel2(/* args */) {
frame.removeAll();
p2 = new Panel2(/* args */);
frame.add(pp, "PlacementPanel");
frame.pack();
frame.validate();
frame.repaint();
}
I'm trying to use updatePanel2 to swap out the existing panel with a new Panel2 but It doesn't seem to be working. Panel2 works fine on it's own but trying to use it in conjunction with my program simply yields a blank window. Any help would be greatly appreciated!
that requires swapping out the current, visible JPanel with another
Have a look at CardLayout for a complete example of how to do it properly.
I have a Swing app which 'swaps' Panels when the user press the 'SPACE' key, showing a live plot of a running simulation. What i did goes like this:
public class MainPanel extends JPanel implements Runnable {
// Called when the JPanel is added to the JFrame
public void addNotify() {
super.addNotify();
animator = new ScheduledThreadPoolExecutor(1);
animator.scheduleAtFixedRate(this, 0, 1000L/60L, TimeUnit.MILLISECONDS);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (spacePressed)
plot.render(g);
else
simulation.render(g);
}
public void run() {
simulation.update();
repaint();
}
}
public class PlotView {
public void render(Graphics g) {
//draw the plot here
}
}
public class SimulationView {
public void render(Graphics g) {
//draw simulation here
}
}
This works very well for my 'show live plot' problem. And there's also the CardLayout approach, which you may turn into a new separate question if you having trouble. Good luck!
You should do .setVisible(false); to the panel which you want to be replaced.
Here is a working example, it switches the panels when you press "ENTER";
If you copy this in an IDE, automatically get the imports (shift+o in Eclipse);
public class MyFrame extends JFrame implements KeyListener {
private JButton button = new JButton("Change Panels");
private JPanel panelOnFrame = new JPanel();
private JPanel panel1 = new JPanel();
public MyFrame() {
// adding labels to panels, to distinguish them
panelOnFrame.add(new JLabel("panel on frame"));
panel1.add(new JLabel("panel 1"));
setSize(new Dimension(250,250));
setDefaultCloseOperation(EXIT_ON_CLOSE);
add(button);
add(panelOnFrame);
setVisible(true);
addKeyListener(this);
addKeyListener(this);
setFocusable(true);
}
public static void main(String[] args) {
MyFrame frame = new MyFrame();
}
#Override
public void keyPressed(KeyEvent k) {
if(k.getKeyCode() == KeyEvent.VK_ENTER){
//+-------------here is the replacement:
panelOnFrame.setVisible(false);
this.add(panel1);
}
}
#Override
public void keyReleased(KeyEvent arg0) {
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}

How to override windowsClosing event in JFrame

i'm developing a JFrame which has a button to show another JFrame. On the second JFrame i want to override WindowsClosing event to hide this frame but not close all the application. So i do like this:
On second JFrame
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
formWindowClosing(evt);
}
});
private void formWindowClosing(java.awt.event.WindowEvent evt) {
this.dispose();
}
but application still close when i click x button on the windows. why? can you help me?
I can't use
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
because i need to show again that JFrame with some information added in it during operations from first JFrame. So i init second JFrame with attribute visible false. if i use dispose i lose the information added in a second moment by the other JFrame. so i use
private void formWindowClosing(java.awt.event.WindowEvent evt) {
this.setVisible(false);
}
but it still continue to terminate my entire app.
don't create a new JFrame, for new container use JDialog, if you want to hide the JFrame then better would be override proper e.g DefaultCloseOperations(JFrame.HIDE_ON_CLOSE), method JFrame.EXIT_ON_CLOSE teminating current JVM instance simlair as calll for System.exit(int)
EDIT
but it still continue to terminate my entire app.
1) then there must be another issue, your code maybe call another JFrame or formWindowClosing <> WindowClosing, use implemented method from API
public void windowClosing(WindowEvent e) {
2) I'b preferred DefaultCloseOperations(JFrame.HIDE_ON_CLOSE),
3) use JDialog instead of JFrame
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ClosingFrame extends JFrame {
private JMenuBar MenuBar = new JMenuBar();
private static JFrame frame = new JFrame();
private static JFrame frame1 = new JFrame("DefaultCloseOperation(JFrame.HIDE_ON_CLOSE)");
private static final long serialVersionUID = 1L;
private JMenu File = new JMenu("File");
private JMenuItem Exit = new JMenuItem("Exit");
public ClosingFrame() {
File.add(Exit);
MenuBar.add(File);
Exit.addActionListener(new ExitListener());
WindowListener exitListener = new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
frame.setVisible(false);
/*int confirm = JOptionPane.showOptionDialog(frame,
"Are You Sure to Close this Application?",
"Exit Confirmation", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
if (confirm == JOptionPane.YES_OPTION) {
System.exit(1);
}*/
}
};
JButton btn = new JButton("Show second JFrame");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame1.setVisible(true);
}
});
frame.add(btn, BorderLayout.SOUTH);
frame.addWindowListener(exitListener);
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame.setJMenuBar(MenuBar);
frame.setPreferredSize(new Dimension(400, 300));
frame.setLocation(100, 100);
frame.pack();
frame.setVisible(true);
}
private class ExitListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
int confirm = JOptionPane.showOptionDialog(frame,
"Are You Sure to Close this Application?",
"Exit Confirmation", JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE, null, null, null);
if (confirm == JOptionPane.YES_OPTION) {
System.exit(1);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ClosingFrame cf = new ClosingFrame();
JButton btn = new JButton("Show first JFrame");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
frame.setVisible(true);
}
});
frame1.add(btn, BorderLayout.SOUTH);
frame1.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame1.setPreferredSize(new Dimension(400, 300));
frame1.setLocation(100, 400);
frame1.pack();
frame1.setVisible(true);
}
});
}
}
Adding a New Code with no WindowListener part as explained by #JBNizet, the very right thing. The default behaviour just hides the window, nothing is lost, you simply have to bring it back, every value inside it will remain as is, below is the sample program for further help :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TwoFrames
{
private SecondFrame secondFrame;
private int count = 0;
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("JFRAME 1");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
secondFrame = new SecondFrame();
secondFrame.createAndDisplayGUI();
secondFrame.tfield.setText("I will be same everytime.");
JPanel contentPane = new JPanel();
JButton showButton = new JButton("SHOW JFRAME 2");
showButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
secondFrame.tfield.setText(secondFrame.tfield.getText() + count);
count++;
if (!(secondFrame.isShowing()))
secondFrame.setVisible(true);
}
});
frame.add(contentPane, BorderLayout.CENTER);
frame.add(showButton, BorderLayout.PAGE_END);
frame.setSize(200, 200);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TwoFrames().createAndDisplayGUI();
}
});
}
}
class SecondFrame extends JFrame
{
private WindowAdapter windowAdapter;
public JTextField tfield;
public void createAndDisplayGUI()
{
setLocationByPlatform(true);
JPanel contentPane = new JPanel();
tfield = new JTextField(10);
addWindowListener(windowAdapter);
contentPane.add(tfield);
getContentPane().add(contentPane);
setSize(300, 300);
}
}
Is this what you want, try this code :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TwoFrames
{
private SecondFrame secondFrame;
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("JFRAME 1");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
secondFrame = new SecondFrame();
secondFrame.createAndDisplayGUI();
secondFrame.tfield.setText("I will be same everytime.");
JPanel contentPane = new JPanel();
JButton showButton = new JButton("SHOW JFRAME 2");
showButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (!(secondFrame.isShowing()))
secondFrame.setVisible(true);
}
});
frame.add(contentPane, BorderLayout.CENTER);
frame.add(showButton, BorderLayout.PAGE_END);
frame.setSize(200, 200);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new TwoFrames().createAndDisplayGUI();
}
});
}
}
class SecondFrame extends JFrame
{
private WindowAdapter windowAdapter;
public JTextField tfield;
public void createAndDisplayGUI()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
JPanel contentPane = new JPanel();
tfield = new JTextField(10);
windowAdapter = new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
};
addWindowListener(windowAdapter);
contentPane.add(tfield);
getContentPane().add(contentPane);
setSize(300, 300);
}
}
You could avoid the listener completely and use
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
Note that the default value is HIDE_ON_CLOSE, so the behavior you want should be the default behavior. Maybe you registered another listener that exits the application.
See http://docs.oracle.com/javase/6/docs/api/javax/swing/JFrame.html#setDefaultCloseOperation%28int%29
It's hard to pinpoint exactly why you are experiencing the behavior stated without seeing a little more of the set-up code, however it may be due to defaultCloseOperation set to EXIT_ON_CLOSE.
Here's a link to a demo displaying the properties you are looking for although the structure is a bit different. Have a look: http://docs.oracle.com/javase/tutorial/uiswing/examples/components/FrameworkProject/src/components/Framework.java

Categories