How to request focus on JComponent after changing JPanel in JFrame - java

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();
}
}

Related

Can I communicate between two JFrames WITHOUT using static variables or methods?

Basically, I'm trying to get the JButton in Frame1 to edit the JLabel in Frame2. I know it can work if I set the JLabel and getLabel() method in Frame2 to static, and have the ActionListener reference Frame1 directly, but I want to know if there's a way to do it without using static variables or methods.
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String[] args) {
Frame2 f2 = new Frame2();
f2.pack();
f2.setLocation(700, 400);
f2.setVisible(true);
Frame1 f1 = new Frame1(f2);
f1.pack();
f1.setLocation(400, 400);
f1.setVisible(true);
}
}
class Frame1 extends JFrame {
JButton button;
public Frame1(JFrame f) {
super("Frame 1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
button = new JButton("Button");
add(button);
button.addActionListener(new Listener(f.getLabel()));
}
}
class Frame2 extends JFrame {
JLabel label;
public Frame2() {
super("Frame 2");
setDefaultCloseOperation(EXIT_ON_CLOSE);
label = new JLabel("hello");
add(label);
}
public JLabel getLabel() {
return label;
}
}
class Listener implements ActionListener {
private JLabel lab;
public Listener(JLabel lab) {
this.lab = lab;
}
public void actionPerformed(ActionEvent e) {
lab.setText("nice");
}
}
Any suggestions? Thanks!
EDIT: Here's a compilable version of the code -- label and getLabel() are static, and the ActionListener references JFrame1 directly when it's called. My goal is to have no static variables or methods (outside of main).
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Test {
public static void main(String[] args) {
Frame2 f2 = new Frame2();
f2.pack();
f2.setLocation(700, 400);
f2.setVisible(true);
Frame1 f1 = new Frame1(f2);
f1.pack();
f1.setLocation(400, 400);
f1.setVisible(true);
}
}
class Frame1 extends JFrame {
JButton button;
public Frame1(JFrame f) {
super("Frame 1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
button = new JButton("Button");
add(button);
button.addActionListener(new Listener(Frame2.getLabel()));
}
}
class Frame2 extends JFrame {
static JLabel label;
public Frame2() {
super("Frame 2");
setDefaultCloseOperation(EXIT_ON_CLOSE);
label = new JLabel("hello");
add(label);
}
public static JLabel getLabel() {
return label;
}
}
class Listener implements ActionListener {
private JLabel lab;
public Listener(JLabel lab) {
this.lab = lab;
}
public void actionPerformed(ActionEvent e) {
lab.setText("nice");
}
}
Oracle has a really nifty Swing tutorial. I think your studying the tutorial would be a really good idea.
I had to make a bunch of changes to your code to get it to execute.
The main change I made was to keep the reference to the JLabel in the Frame2 class. I passed an instance of Frame2 to the Listener class. Just like I did yesterday with your previous question.
Here's the code. Take the time to study what I did before you ask another question tomorrow.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DoubleJFrameTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Frame2 f2 = new Frame2();
f2.pack();
f2.setLocation(700, 400);
f2.setVisible(true);
Frame1 f1 = new Frame1(f2);
f1.pack();
f1.setLocation(400, 400);
f1.setVisible(true);
}
});
}
}
class Frame1 extends JFrame {
private static final long serialVersionUID = 1L;
private JButton button;
public Frame1(Frame2 f) {
super("Frame 1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
button = new JButton("Button");
button.addActionListener(new Listener(f));
panel.add(button, BorderLayout.CENTER);
add(panel);
}
}
class Frame2 extends JFrame {
private static final long serialVersionUID = 1L;
private JLabel label;
public Frame2() {
super("Frame 2");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
label = new JLabel("hello");
panel.add(label, BorderLayout.CENTER);
add(panel);
}
public void setLabelText(String text) {
label.setText(text);;
}
}
class Listener implements ActionListener {
private Frame2 frame;
public Listener(Frame2 frame) {
this.frame = frame;
}
#Override
public void actionPerformed(ActionEvent e) {
frame.setLabelText("nice");
}
}

Repainting a JPanel

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.

Using card layout, cards not swapping?

I want to keep my Controller panel as type JPanel as I will be incorporating into a tab later, I want to swap between Main and NextPage using buttons on those specific screens, I don't want to have consistent buttons on the bottom for both screens that switch between cards(i.e I don't want to have add & back to be appearing on both screens), I am trying to get the add button in Main to go to NextPage and back button in NextPage to go to Main. This is what I have so far:
For Controller:
import java.awt.CardLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Controller extends JPanel {
private static Controller instance = new Controller();
JPanel cards;
Main mainPanel;
NextPage nextPage;
public Controller() {
setLayout(new BorderLayout());
setSize(810, 510);
cards = new JPanel(new CardLayout());
mainPanel = new Main();
nextPage = new NextPage();
cards.add(mainPanel, "Main");
cards.add(nextPage, "Next");
add(cards);
setVisible(true);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("MainPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Controller con = new Controller();
frame.getContentPane().add(con);
frame.setSize(800, 600);
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public void changeCard(String card) {
CardLayout cl = (CardLayout) (cards.getLayout());
cl.show(cards, card);
}
public static Controller getInstance() {
return instance;
}
}
For main:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
public class Main extends JPanel implements ActionListener {
private JButton search, add, delete;
private JTextField textField;
public Main() {
search = new JButton("Search");
add = new JButton("Add");
delete = new JButton("Delete");
textField = new JTextField(20);
add.addActionListener(this);
delete.addActionListener(this);
setLayout(new BorderLayout());
JPanel top = new JPanel();
top.add(search);
add(top, BorderLayout.NORTH);
JPanel bottom = new JPanel();
bottom.add(add);
bottom.add(delete);
add(bottom, BorderLayout.SOUTH);
setVisible(true);
setSize(400, 500);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == add) {
Controller.getInstance().changeCard("Next");
} else if (e.getSource() == delete) {
System.out.println("do something");
}
}
}
For NextPage:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
public class NextPage extends JPanel implements ActionListener {
private JButton back;
private JTextField textField;
public NextPage() {
back = new JButton("Back");
textField = new JTextField(20);
back.addActionListener(this);
setLayout(new BorderLayout());
add(back);
setVisible(true);
setSize(400, 500);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == back) {
Controller.getInstance().changeCard("Next");
}
}
}
Check out Card Layout Actions.
It is an extension of CardLayout that provides you with Previous/Next buttons that you can easily add to a panel separate from the CardLayout.

How to pass value JList item from JFrame into another JFrame (just value)?

I have write a test with two class.
The first JPanel, Gestion: JFrame with jlist + button (the button open the Jlist 2, PanelTest)
The second JPanel, PanelTest: JFrame and I want to recover in String, the select value item in the JFrame Gestion (JList)
How to do that ?
Gestion.java:
package IHM;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.List;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.JList;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.SQLException;
public class Gestion extends JFrame {
private DocumentListener myListener;
public String test;
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Gestion frame = new Gestion();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public String getTest() {
return test;
}
/**
* Create the frame.
* #throws Exception
*/
public Gestion() throws Exception {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
final PanelTest panel2 = new PanelTest();
JPanel panel = new JPanel();
contentPane.add(panel, BorderLayout.NORTH);
String choix[] = {" Pierre", " Paul", " Jacques", " Lou", " Marie"};
final JList list = new JList(choix);
panel.add(list);
list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent arg0) {
test = (String) list.getSelectedValue();
System.out.println(test);
// PanelTest.setValue(test);
}
});
JPanel panel_1 = new JPanel();
contentPane.add(panel_1, BorderLayout.SOUTH);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
new PanelTest().setVisible(true);
fermerFenetre();
}
});
panel_1.add(btnNewButton);
}
public void fermerFenetre(){
this.setVisible(false);
}
}
PanelTest.java
package IHM;
import java.awt.BorderLayout;
public class PanelTest extends JFrame {
public String tyty;
private JPanel contentPane;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
PanelTest frame = new PanelTest();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public PanelTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
textField = new JTextField();
contentPane.add(textField, BorderLayout.WEST);
textField.setColumns(10);
}
}
Suggestions:
Make your list variable a field, not a local variable, or else make it a final local variable so that it is accessible inside of the anonymous ActionListener.
Obtain the selected list item in your ActionListener where you launch the 2nd window.
Pass that String into your PanelTest object via a String parameter.
The second window should be a dialog such as a JDialog, not a JFrame.
As an aside, you'll rarely want to have your GUI classes extend top level windows such as JFrames or JDialogs as that greatly limits the flexibility of your GUI code.
For example,
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class Gestion2 extends JPanel {
private static final String CHOIX[] = { " Pierre", " Paul", " Jacques",
" Lou", " Marie" };
private JList<String> choixList = new JList<>(CHOIX);
public Gestion2() {
JPanel listPanel = new JPanel();
listPanel.add(new JScrollPane(choixList));
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new ListSelectAction("Select Item and Press")));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(listPanel);
add(btnPanel);
}
private class ListSelectAction extends AbstractAction {
public ListSelectAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
String selectedItem = choixList.getSelectedValue();
if (selectedItem != null) {
PanelTest2 panelTest2 = new PanelTest2(selectedItem);
Component component = (Component) e.getSource();
Window win = SwingUtilities.getWindowAncestor(component);
// JOptionPane example
JOptionPane.showMessageDialog(win, panelTest2,
"JOptionPane Example", JOptionPane.PLAIN_MESSAGE);
// or JDialog example
JDialog dialog = new JDialog(win, "JDialog Example",
ModalityType.APPLICATION_MODAL);
dialog.add(panelTest2);
dialog.pack();
dialog.setLocationRelativeTo(win);
dialog.setVisible(true);
}
}
}
private static void createAndShowGui() {
Gestion2 mainPanel = new Gestion2();
JFrame frame = new JFrame("Gestion2");
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();
}
});
}
}
#SuppressWarnings("serial")
class PanelTest2 extends JPanel {
private String selectedItem;
private JTextField textField = new JTextField(10);
public PanelTest2(String selectedItem) {
this.selectedItem = selectedItem;
textField.setText(selectedItem);
add(new JLabel("Selected Item:"));
add(textField);
}
public String getSelectedItem() {
return selectedItem;
}
}

GUI multiple frames switch

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.

Categories