I have two frames with contents . The first one has a jlabel and jbutton which when it is clicked it will open a new frame. I need to repaint the first frame or the panel that has the label by adding another jlabel to it when the second frame is closed.
//Edited
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class FirstFrame extends JPanel implements KeyListener{
private static String command[];
private static JButton ok;
private static int count = 1;
private static JTextField text;
private static JLabel labels[];
private static JPanel p ;
private static JFrame frame;
public int getCount(){
return count;
}
public static void createWindow(){
JFrame createFrame = new JFrame();
JPanel panel = new JPanel(new GridLayout(2,1));
text = new JTextField (30);
ok = new JButton ("Add");
ok.requestFocusInWindow();
ok.setFocusable(true);
panel.add(text);
panel.add(ok);
text.setFocusable(true);
text.addKeyListener(new FirstFrame());
createFrame.add(panel);
createFrame.setVisible(true);
createFrame.setSize(600,300);
createFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
createFrame.setLocationRelativeTo(null);
createFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.out.println(command[count]);
if(command[count] != null){
p.add(new JLabel("NEW LABEL"));
p.revalidate();
p.repaint();
count++;
System.out.println(count);
}
}
});
if(count >= command.length)
count = 1;
ok.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(command[count] == null)
command[count] = text.getText();
else
command[count] = command[count]+", "+text.getText();
text.setText("");
}
});
}
public FirstFrame(){
p = new JPanel();
JButton create = new JButton ("CREATE");
command = new String[2];
labels = new JLabel[2];
addKeyListener(this);
create.setPreferredSize(new Dimension(200,100));
//setLayout(new BorderLayout());
p.add(new JLabel("dsafsaf"));
p.add(create);
add(p);
//JPanel mainPanel = new JPanel();
/*mainPanel.setFocusable(false);
mainPanel.add(create);
*/
create.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
createWindow();
}
});
//add(mainPanel, BorderLayout.SOUTH);
}
public static void main(String[] args) {
frame = new JFrame();
frame.add(new FirstFrame());
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER)
if(ok.isDisplayable()){
ok.doClick();
return;}
}
}
}
});
}
}
As per my first comment, you're better off using a dialog of some type, and likely something as simple as a JOptionPane. For instance in the code below, I create a new JLabel with the text in a JTextField that's held by a JOptionPane, and then add it to the original GUI:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class FirstPanel2 extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = 300;
private JTextField textField = new JTextField("Hovercraft rules!", 30);
private int count = 0;
public FirstPanel2() {
AddAction addAction = new AddAction();
textField.setAction(addAction);
add(textField);
add(new JButton(addAction));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class AddAction extends AbstractAction {
public AddAction() {
super("Add");
}
#Override
public void actionPerformed(ActionEvent e) {
String text = textField.getText();
final JTextField someField = new JTextField(text, 10);
JPanel panel = new JPanel();
panel.add(someField);
int result = JOptionPane.showConfirmDialog(FirstPanel2.this, panel, "Add Label",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
JLabel label = new JLabel(someField.getText());
FirstPanel2.this.add(label);
FirstPanel2.this.revalidate();
FirstPanel2.this.repaint();
}
}
}
private static void createAndShowGui() {
FirstPanel2 mainPanel = new FirstPanel2();
JFrame frame = new JFrame("My Gui");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Also, don't add KeyListeners to text components as that is a dangerous and unnecessary thing to do. Here you're much better off adding an ActionListener, or as in my code above, an Action, so that it will perform an action when the enter key is pressed.
Edit
You ask:
Just realized it is because of the KeyListener. Can you explain please the addAction ?
This is functionally similar to adding an ActionListener to a JTextField, so that when you press enter the actionPerformed(...) method will be called, exactly the same as if you pressed a JButton and activated its ActionListener or Action. An Action is like an "ActionListener" on steroids. It not only behaves as an ActionListener, but it can also give the button its text, its icon and other properties.
Related
I have these two classes:
class Test:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
//frame
private static JFrame frame = new JFrame() {
private static final long serialVersionUID = 1L;
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 200);
setLocationRelativeTo(null);
setLayout(new BorderLayout());
viewPanel = new JPanel(new BorderLayout());
add(viewPanel);
}
};
private static JPanel viewPanel;
//change the panels
public static void showView(JPanel panel) {
viewPanel.removeAll();
viewPanel.add(panel, BorderLayout.CENTER);
viewPanel.revalidate();
viewPanel.repaint();
}
//main method
public static void main (String [] args) {
SwingUtilities.invokeLater(() -> showView(Panels.panel1));
SwingUtilities.invokeLater(() -> {
frame.setVisible(true);
});
}
}
class Panels:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
//panels
public class Panels {
//first panel
static JPanel panel1 = new JPanel() {
private static final long serialVersionUID = 1L;
{
JButton button = new JButton("Click here!");
add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
SwingUtilities.invokeLater(() -> Test.showView(panel2));
}
});
}
};
//second panel
static JPanel panel2 = new JPanel() {
private static final long serialVersionUID = 1L;
{
JTextField textField = new JTextField(5);
add(textField);
}
};
}
And as you can see, the JPanel changes inside the JFrame, after clicking the JButton: How can I change the JPanel from another Class?
But how can I now set the focus on the JTextField, after changing panel1 to panel2?
I've tried to add grabFocus(); to the JTextField, but it didn't work and requestFocus(); didn't work as well.
Thanks in advance!
There's no need to call showView(...) with invokeLater. Your ActionListener is being called on the EDT, so this is unnecessary code.
If you had a handle to the JTextField, you could call requestFocusInWindow() on it after making it visible, and it should have focus.
For example:
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// SwingUtilities.invokeLater(() -> Test.showView(panel2)); // not needed
Test.showView(panel2);
Component[] comps = panel2.getComponents();
if (comps.length > 0) {
comps[0].requestFocusInWindow();
}
}
});
Myself, I would use CardLayout to do my swapping and would not use the kludge of getting components via getComponents() but rather using much less brittle method calls.
For example:
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class MyPanelTest extends JPanel {
private TextFieldPanel textFieldPanel = new TextFieldPanel();
private CardLayout cardLayout = new CardLayout();
public MyPanelTest() {
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new ButtonAction("Press Me")));
setPreferredSize(new Dimension(400, 200));
setLayout(cardLayout);
add(buttonPanel, "button panel");
add(textFieldPanel, TextFieldPanel.NAME);
}
private class ButtonAction extends AbstractAction {
public ButtonAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(MyPanelTest.this, TextFieldPanel.NAME);
textFieldPanel.textFieldRequestFocus();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("My Panel Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyPanelTest());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class TextFieldPanel extends JPanel {
public static final String NAME = "TEXT_FIELD_PANEL";
private JTextField textField = new JTextField(10);
public TextFieldPanel() {
add(textField);
}
public void textFieldRequestFocus() {
textField.requestFocusInWindow();
}
}
I cannot get my Jframe to close when a user hits the (X) button. I tried many ways to do them but none of them work.
I tried:
JFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Nothing happens. My main class extends jframe and implements action listener. What am I doing wrong?
My code:
package com.xflare.Bot;
import static java.lang.System.out;
import java.awt.*;
import java.lang.String;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Main extends JFrame implements ActionListener{
private static Frame frame;
private static boolean debug = true;
private static boolean enabled = true;
private static JButton exitbutton; // reference to the button object
private static JButton webbutton; // reference to the button object
private static JButton aboutbutton; // reference to the button object
public static void main(String[] args) {
new Main().start();
}
private void start(){
//start up
printSystem("starting");
//create frame
printSystem("Creating a frame...");
createFrame();
//create button(s)
createQuitButton();
createWebButton();
createAboutButton();
//Spawn init.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getFrame().setResizable(false);
getFrame().setVisible(true);
printSystem("Started up successfully!");
}
private void createFrame(){
Main.frame = new Frame("app");
frame.setSize(600, 300);
}
private void createQuitButton(){
exitbutton = new JButton("Exit!");
getFrame().setLayout(null);
exitbutton.setBounds(225,45,150,75);//setBounds(x,y,width,height)
exitbutton.setActionCommand("exit");
exitbutton.addActionListener(this);
getFrame().add(exitbutton);
}
private void createWebButton(){
webbutton = new JButton("Open hacked browser");
getFrame().setLayout(null);
webbutton.setBounds(225,130,150,75);//setBounds(x,y,width,height)
webbutton.setActionCommand("web");
webbutton.addActionListener(this);
getFrame().add(webbutton);
}
private void createAboutButton(){
aboutbutton = new JButton("About");
getFrame().setLayout(null);
aboutbutton.setBounds(225,215,150,75);//setBounds(x,y,width,height)
aboutbutton.setActionCommand("about");
aboutbutton.addActionListener(this);
getFrame().add(aboutbutton);
}
private Frame getFrame(){
return Main.frame;
}
public void actionPerformed(ActionEvent e) {
String actionCommand = ((JButton) e.getSource()).getActionCommand();
printDebug("Button " + actionCommand + " was pressed.");
if(actionCommand.equals("exit")){
exitbutton.setVisible(false);
shutdown();
}
else if(actionCommand.equals("about")){
aboutbutton.setVisible(false);
webbutton.setVisible(false);
exitbutton.setVisible(false);
showAbout();
}
else{
printCritical("Unknown button pressed!");
}
}
private void showAbout(){
}
private void shutdown(){
printSystem("Attempting to shut down...");
enabled = false;
printSystem("Shut down successful!");
System.exit(0);
}
private boolean debugEnabled(){
return debug;
}
private String getVersion(){
return "1.0.0";
}
private String getCodename(){
return "[BeastReleased]";
}
private static void printSystem(String var){
out.println("System> " + var);
}
private static void printError(String var){
out.println("Error> " + var);
}
private static void printCritical(String var){
out.println("Critical> " + var);
}
private void printDebug(String var){
if(debugEnabled()) {
out.println("Debug> " + var);
}
}
}
Link to same code: http://pastebin.com/1fDbjm74
This: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
needs to be called on the JFrame that you're actually displaying, Main.frame. You're not doing this.
getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getFrame().setVisible(true);
You've got too many Frame / JFrames. Your class extends JFrame but you're not displaying it. You've also got a Frame variable called frame, (NOT a JFrame variable) that you are displaying, and of course since this is not a JFrame, you can't make JFrame method calls, like the one above on it.
Simplify: create ONE JFrame not a Frame, and call this method on it and set it visible. So either get rid of the frame variable and use the class itself, the this, as your JFrame, and display it, or don't have your class extend JFrame and use your frame variable, but make it a JFrame object not a Frame object, since Frame does not have the setDefaultCloseOperation(...) method.
Also you're over-using static modifiers where they shouldn't be used. All your fields should be instance (non-static) fields.
Also, use of null layouts and setBounds will bite you in the end. For instance when I run your program, portions of the middle button's text are missing because its size has been artificially constrained in a bad way. Much better is to us layout managers to your advantage. For example:....
Please have a look at this program structure:
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class MyMain extends JPanel {
public static final String MENU_PANEL = "MENU";
public static final String ABOUT_PANEL = "About";
private CardLayout cardLayout = new CardLayout();
public MyMain() {
JPanel aboutPanel = new JPanel(new GridBagLayout());
JLabel aboutLabel = new JLabel("About");
aboutLabel.setFont(aboutLabel.getFont().deriveFont(Font.BOLD, 32));
aboutPanel.add(aboutLabel);
JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 10, 10));
buttonPanel.add(createButton(new ExitAction("Exit!", KeyEvent.VK_X)));
buttonPanel.add(createButton(new OpenBrowserAction("Open Hacked Browser", KeyEvent.VK_O)));
buttonPanel.add(createButton(new AboutAction("About", KeyEvent.VK_A, this)));
JPanel menuPanel = new JPanel(new GridBagLayout());
int ebGap = 40;
menuPanel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
menuPanel.add(buttonPanel);
setLayout(cardLayout);
add(menuPanel, MENU_PANEL);
add(aboutPanel, ABOUT_PANEL);
}
private JButton createButton(Action action) {
JButton button = new JButton(action);
Font btnFont = button.getFont().deriveFont(Font.BOLD, 20);
button.setFont(btnFont);
return button;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("My Main Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyMain());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
public void showPanel(String cardLayoutKey) {
cardLayout.show(this, cardLayoutKey);
}
}
class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Component comp = (Component) e.getSource();
if (comp != null) {
Window win = SwingUtilities.getWindowAncestor(comp);
if (win != null) {
win.dispose();
}
}
}
}
class OpenBrowserAction extends AbstractAction {
public OpenBrowserAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Open Browswer");
}
}
class AboutAction extends AbstractAction {
private MyMain myMain;
public AboutAction(String name, int mnemonic, MyMain myMain) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.myMain = myMain;
}
#Override
public void actionPerformed(ActionEvent e) {
if (myMain != null) {
myMain.showPanel(MyMain.ABOUT_PANEL);
}
}
}
You are calling the setDefaultCloseOperation method on the wrong place. Here's what you should do:
private void start(){
//start up
printSystem("starting");
//create frame
printSystem("Creating a frame...");
createFrame();
//Spawn init.
getFrame().setResizable(false);
getFrame().setVisible(true);
printSystem("Started up successfully!");
}
private void createFrame(){
Main.frame = new Frame("app");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 300);
}
after looking for an answer for 3 hours, I am just about to give up on this idea:
I am making an application that displays the followers of a Twitch streamer.
A couple of features i am trying to add:
the display frame is a separate window from the controls frame.
I am trying to use (JFrame as display window) (JDialog as controls frame)
And furthermore: Settings is in another JDialog (this one has Modal(true))
Settings needs to be able to send the JFrame information such as: "username" and "text color"
And the settings JDialog will only pop up from clicking "settings" on the controls JDialog.
It will setVisible(false) when you click "save settings" or the X.
On the controls JDialog (b_console) needs to receive error messages and info like that.
And on the same JDialog, "filler" needs to receive follower count and things like that.
Here follows my code involving the transfers listed above:
package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics.*;
import javax.swing.*;
import java.io.*;
import java.net.URL;
public class JavaFollowerNotifier extends JFrame implements ComponentListener
{
Settings settings = new Settings();
ControlPanel ctrlPnl = new ControlPanel();
public JavaFollowerNotifier()
{
try
{
settings.readSettings();
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void grabFollower()
{
ctrlPnl.b_console.setText("Retrieving Info...");
try
{
URL twitch = new URL("https://api.twitch.tv/kraken/channels/" + savedSettings[1] + "/follows?limit=1&offset=0");
ctrlPnl.b_console.setText("Retrieved");
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void grabStats()
{
ctrlPnl.b_console.setText("Retrieving Info...");
try
{
URL twitch = new URL("https://api.twitch.tv/kraken/channels/" + savedSettings[1] + "/follows?limit=1&offset=0");
ctrlPnl.filler.setText("Followers: " + totalFollowers + "\nLatest: " + lastFollower);
ctrlPnl.b_console.setText("Retrieved");
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void componentMoved(ComponentEvent arg0)
{
//this is only to *attach this JDialog to the JFrame and make it move together my plan is to have it undecorated as well
int x = this.getX() + this.getWidth();
int y = this.getY();
ctrlPnl.movePanel(x, y);
}
public void paint(Graphics g)
{
if(clearPaint == false)
{
//any "savedSettings[n]" are saved in Settings.java (just not in this version)
g.setColor(Color.decode(savedSettings[3]));
scaledFont = scaleFont(follower + " followed!", bounds, g, new Font(savedSettings[2], Font.PLAIN, 200));
}
}
}
package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Settings extends JDialog implements ActionListener
{
JavaFollowerNotifier jfollow = new JavaFollowerNotifier();
ControlPanel ctrlPnl = new ControlPanel();
//here are the settings mention above
String[] savedSettings = {"imgs/b_b.jpg","username","font","color","Nightbot"};
public Settings()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
}
public void saveSettings()
{
savedSettings[4] = jfollow.lastFollower;
try
{
PrintWriter save = new PrintWriter("config.cfg");
ctrlPnl.b_console.setText("Saving...");
for(int i = 0; i < 5; i++)
{
save.println(savedSettings[i]);
}
save.close();
ctrlPnl.b_console.setText("Saved");
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
canClose = false;
}
readSettings();
this.repaint();
}
public void readSettings()
{
ctrlPnl.b_console.setText("Loading...");
try
{
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
jfollow.lastFollower = savedSettings[4];
try
{
}
catch(Exception e)
{
ctrlPnl.b_console.setText("Error");
System.out.println(e);
}
ctrlPnl.b_console.setText("Loaded Settings");
}
}
package javafollowernotifier;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ControlPanel extends JDialog implements ActionListener
{
public ControlPanel()
{
try
{
}
catch (Exception e)
{
b_console.setText("Error");
System.out.println(e);
}
}
public void movePanel(int x, int y)
{
//here is where i *attach the JDialog to the JFrame
controlPanel.setLocation(x, y);
}
public void actionPerformed(ActionEvent ie)
{
if(ie.getSource() == b_settings)
{
settings.frame.setVisible(true);
}
}
}
I tried to fix your program, but I wasn't too sure about its flow. So I created another simple one. What I did was pass the labels from the main frame to the dialogs' constructors. In the dialog, I took those labels and changed them with text entered in their text fields. If you hit enter after writing text from the dialog, you'll see the text in the frame change
public class JavaFollowerNotifier1 extends JFrame{
private JLabel controlDialogLabel = new JLabel(" ");
private JLabel settingDialogLabel = new JLabel(" ");
private ControlDialog control;
private SettingsDialog settings;
public JavaFollowerNotifier1() {
control = new ControlDialog(this, true, controlDialogLabel);
settings = new SettingsDialog(this, true, settingDialogLabel);
....
class ControlDialog extends JDialog {
private JLabel label;
public ControlDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
....
class SettingsDialog extends JDialog {
private JLabel label;
public SettingsDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
Test it out and let me know if you have any questions
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class JavaFollowerNotifier1 extends JFrame{
private JLabel controlDialogLabel = new JLabel(" ");
private JLabel settingDialogLabel = new JLabel(" ");
private JButton showControl = new JButton("Show Control");
private JButton showSetting = new JButton("Show Settings");
private ControlDialog control;
private SettingsDialog settings;
public JavaFollowerNotifier1() {
control = new ControlDialog(this, true, controlDialogLabel);
settings = new SettingsDialog(this, true, settingDialogLabel);
showControl.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
control.setVisible(true);
}
});
showSetting.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
settings.setVisible(true);
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(showControl);
buttonPanel.add(showSetting);
add(buttonPanel, BorderLayout.SOUTH);
add(controlDialogLabel, BorderLayout.NORTH);
add(settingDialogLabel, BorderLayout.CENTER);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JavaFollowerNotifier1();
}
});
}
}
class ControlDialog extends JDialog {
private JLabel label;
private JTextField field = new JTextField(15);
private JButton button = new JButton("Close");
private String s = "";
public ControlDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
setLayout(new BorderLayout());
add(field, BorderLayout.NORTH);
add(button, BorderLayout.CENTER);
pack();
setLocationRelativeTo(frame);
field.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
s = field.getText();
label.setText("Message from Control Dialog: " + s);
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
ControlDialog.this.setVisible(false);
}
});
}
}
class SettingsDialog extends JDialog {
private JLabel label;
private JTextField field = new JTextField(15);
private JButton button = new JButton("Close");
private String s = "";
public SettingsDialog(final Frame frame, boolean modal, final JLabel label) {
super(frame, modal);
this.label = label;
setLayout(new BorderLayout());
add(field, BorderLayout.NORTH);
add(button, BorderLayout.CENTER);
pack();
setLocationRelativeTo(frame);
field.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
s = field.getText();
label.setText("Message from Settings Dialog: " + s);
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
SettingsDialog.this.setVisible(false);
}
});
}
}
Typically when I build GUI's which use modal dialogs to gather user input, I build my own class, which extends the JDialog or in some cases a JFrame. In that class I expose a getter method for an object which I usually call DialgResult. This object acts as the Model for the input I gather from the user. In the class that has the button, or whatever control which triggers asking the user for the information, I create it, show it as a modal dialog, then when it is closed, I retrieve the object using that same getter.
This is a very primitive example:
package arg;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class asdfas extends JFrame {
public static void main(String[] args) {
asdfas ex = new asdfas();
ex.setVisible(true);
}
public asdfas() {
init();
}
private void init() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setBounds(100,100,200,200);
final JButton button = new JButton("Show modal dialog");
button.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Dialog d = new Dialog();
d.setVisible(true);
button.setText(d.getDialogResult().value);
revalidate();
repaint();
}
});
this.add(button);
}
class DialogResult {
public String value;
}
class Dialog extends JDialog {
JTextField tf = new JTextField(20);
private DialogResult result = new DialogResult();
public Dialog() {
super();
init();
}
private void init() {
this.setModal(true);
this.setSize(new Dimension(100,100));
JButton ok = new JButton("ok");
ok.addActionListener( new ActionListener () {
#Override
public void actionPerformed(ActionEvent arg0) {
result = new DialogResult();
result.value = tf.getText();
setVisible(false);
}
});
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
p.add(tf);
p.add(ok);
this.add(p);
}
public DialogResult getDialogResult() {
return result;
}
}
}
For Example:
When JButton1 click JInternalFrame1 Show on the JDesktopPane
And when JButton2 Click JInternalFrame1 Close and JInternalFrame2 Show on the JDesktopPane.
thx before
Edit: with code from comment
if (JInternalFrame1 == null) {
JInternalFrame1 = new FJInternalFrame();
Desktop.add(JInternalFrame1);
JInternalFrame1.toFront();
} else {
JInternalFrame1.dispose();
}
Take a look at this example. I created a custom JInternalFrame that has a different title every time you create a new frame. when you click on the button, a new one is created and the old one disapears
Here is the important code that may help you out. I add a new frame if the desktop size is equal to 0, other wise I remove the previous one, add a new frame, and revalidate
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (desktop.getAllFrames().length == 0) {
desktop.add(new MyInternalFrame());
} else {
desktop.remove(0);
desktop.add(new MyInternalFrame());
revalidate();
repaint();
}
}
});
Here is the complete code. It's two different files.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class InternalFrameDemo1 extends JPanel {
JDesktopPane desktop;
JButton button;
public InternalFrameDemo1() {
desktop = new JDesktopPane();
button = new JButton("Get Next Frame");
setLayout(new BorderLayout());
add(desktop, BorderLayout.CENTER);
add(button, BorderLayout.SOUTH);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (desktop.getAllFrames().length == 0) {
desktop.add(new MyInternalFrame());
} else {
desktop.remove(0);
desktop.add(new MyInternalFrame());
revalidate();
repaint();
}
}
});
}
public static void createAndShowGui() {
JFrame frame = new JFrame();
frame.add(new InternalFrameDemo1());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
import javax.swing.JInternalFrame;
public class MyInternalFrame extends JInternalFrame {
static int openFrameCount = 0;
static final int xOffset = 30, yOffset = 30;
public MyInternalFrame() {
super("Document #" + (++openFrameCount),
true, //resizable
true, //closable
true, //maximizable
true);//iconifiable
setSize(300,300);
setLocation(xOffset*openFrameCount, yOffset*openFrameCount);
setVisible(true);
}
}
I am writing a program for a black jack game. It is an assignment we are not to use gui's but I am doing it for extra credit I have created two frames ant they are working. On the second frame I want to be able to switch back to the first when a button is pressed. How do I do this?
first window.............
import javax.swing.* ;
import java.awt.event.* ;
import java.awt.* ;
import java.util.* ;
public class BlackJackWindow1 extends JFrame implements ActionListener
{
private JButton play = new JButton("Play");
private JButton exit = new JButton("Exit");
private JPanel pane=new JPanel();
private JLabel lbl ;
public BlackJackWindow1()
{
super();
JPanel pane=new JPanel();
setTitle ("Black Jack!!!!!") ;
JFrame frame = new JFrame("");
setVisible(true);
setSize (380, 260) ;
setLocation (450, 200) ;
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ;
setLayout(new FlowLayout());
play = new JButton("Start");
exit = new JButton("exit");
lbl = new JLabel ("Welcome to Theodores Black Jack!!!!!");
add (lbl) ;
add(play, BorderLayout.CENTER);
play.addActionListener (this);
add(exit,BorderLayout.CENTER);
exit.addActionListener (this);
}
#Override
public void actionPerformed(ActionEvent event)
{
// TODO Auto-generated method stub
BlackJackWindow2 bl = new BlackJackWindow2();
if (event.getSource() == play)
{
bl.BlackJackWindow2();
}
else if(event.getSource() == exit){
System.exit(0);
}
}
second window....
import javax.swing.* ;
import java.awt.event.* ;
import java.awt.* ;
import java.util.* ;
public class BlackJackWindow2 extends JFrame implements ActionListener
{
private JButton hit ;
private JButton stay ;
private JButton back;
//private JLabel lbl;
public void BlackJackWindow2()
{
// TODO Auto-generated method stub
JPanel pane=new JPanel();
setTitle ("Black Jack!!!!!") ;
JFrame frame = new JFrame("");
setVisible(true);
setSize (380, 260) ;
setLocation (450, 200) ;
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ;
setLayout(new FlowLayout());
hit = new JButton("Hit");
stay = new JButton("stay");
back = new JButton("return to main menu");
// add (lbl) ;
add(hit, BorderLayout.CENTER);
hit.addActionListener (this) ;
add(stay,BorderLayout.CENTER);
stay.addActionListener (this) ;
add(back,BorderLayout.CENTER);
back.addActionListener (this) ;
}
#Override
public void actionPerformed(ActionEvent event)
{
// TODO Auto-generated method stub
BlackJackWindow1 bl = new BlackJackWindow1();
if (event.getSource() == hit)
{
//code for the game goes here i will complete later
}
else if(event.getSource() == stay){
//code for game goes here i will comeplete later.
}
else
{
//this is where i want the frame to close and go back to the original.
}
}
}
The second frame needs a reference to the first frame so that it can set the focus back to the first frame.
Also your classes extend JFrame but they are also creating other frames in their constructors.
A couple of suggestions:
You're adding components to a JPanel that uses FlowLayout but are using BorderLayout constants when doing this which you shouldn't do as it doesn't make sense:
add(play, BorderLayout.CENTER);
Rather, if using FlowLayout, just add the components without those constants.
Also, rather than swap JFrames, you might want to consider using a CardLayout and swapping veiws in a single JFrame. For instance:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FooBarBazDriver {
private static final String INTRO = "intro";
private static final String GAME = "game";
private CardLayout cardlayout = new CardLayout();
private JPanel mainPanel = new JPanel(cardlayout);
private IntroPanel introPanel = new IntroPanel();
private GamePanel gamePanel = new GamePanel();
public FooBarBazDriver() {
mainPanel.add(introPanel.getMainComponent(), INTRO);
mainPanel.add(gamePanel.getMainComponent(), GAME);
introPanel.addBazBtnActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardlayout.show(mainPanel, GAME);
}
});
gamePanel.addBackBtnActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardlayout.show(mainPanel, INTRO);
}
});
}
private JComponent getMainComponent() {
return mainPanel;
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Foo Bar Baz");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new FooBarBazDriver().getMainComponent());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class IntroPanel {
private JPanel mainPanel = new JPanel();
private JButton baz = new JButton("Baz");
private JButton exit = new JButton("Exit");
public IntroPanel() {
mainPanel.setLayout(new FlowLayout());
baz = new JButton("Start");
exit = new JButton("exit");
mainPanel.add(new JLabel("Hello World"));
mainPanel.add(baz);
mainPanel.add(exit);
exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor(mainPanel);
win.dispose();
}
});
}
public void addBazBtnActionListener(ActionListener listener) {
baz.addActionListener(listener);
}
public JComponent getMainComponent() {
return mainPanel;
}
}
class GamePanel {
private static final Dimension MAIN_SIZE = new Dimension(400, 200);
private JPanel mainPanel = new JPanel();
private JButton foo;
private JButton bar;
private JButton back;
public GamePanel() {
foo = new JButton("Foo");
bar = new JButton("Bar");
back = new JButton("return to main menu");
mainPanel.add(foo);
mainPanel.add(bar);
mainPanel.add(back);
mainPanel.setPreferredSize(MAIN_SIZE);
}
public JComponent getMainComponent() {
return mainPanel;
}
public void addBackBtnActionListener(ActionListener listener) {
back.addActionListener(listener);
}
}
Since I had to test it myself if it is in fact so easy to implement, I built this simple example. It demonstrates a solution to your problem. Slightly inspired by #jzd's answer (+1 for that).
import java.awt.Color;
import java.awt.HeadlessException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class FocusChangeTwoFrames
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createGUI();
}
});
}
private static void createGUI() throws HeadlessException
{
final JFrame f2 = new JFrame();
f2.getContentPane().setBackground(Color.GREEN);
final JFrame f1 = new JFrame();
f1.getContentPane().setBackground(Color.RED);
f1.setSize(400, 300);
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setVisible(true);
MouseListener ml = new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e)
{
if(f1.hasFocus())
f2.requestFocus();
else
f1.requestFocus();
}
};
f1.addMouseListener(ml);
f2.setSize(400, 300);
f2.setLocation(200, 150);
f2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f2.setVisible(true);
f2.addMouseListener(ml);
}
}
Enjoy, Boro.