I am making a program which displays 3 buttons, and when user clicks on "single player", it activates mouse listener which creates new panel, and is supposed to replace the existing panel with that newly created panel. But all I get after I click "single player" is the new window with white empty background. Here is the code:
public class UserInterface extends JFrame {
private JLabel singlePlayer,multiPlayer,quit;
private Container menu;
public JPanel mainPanel,fieldPanel;
private Field field;
private Snake snake1,snake2;
private Food food;
public UserInterface(){
// Adjust window
mainPanel=new JPanel();
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
mainPanel.setSize(700, 500);
setSize(710, 510);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(false);
setTitle("Snake");
//add(mainPanel);
setVisible(true);
this.getContentPane().setBackground(Color.ORANGE);
//mainPanel.setBackground(Color.GREEN);
// Instantiate buttons
singlePlayer=new JLabel();
multiPlayer=new JLabel();
quit=new JLabel();
singlePlayer.setIcon(new ImageIcon("files/singleplayer.jpg"));
multiPlayer.setIcon(new ImageIcon("files/multiplayer.jpg"));
quit.setIcon(new ImageIcon("files/quit.jpg"));
quit.addMouseListener(new Mouse());
singlePlayer.addMouseListener(new Mouse());
multiPlayer.addMouseListener(new Mouse());
// Create menu panel
menu=new JPanel(new GridLayout(3,1,0,0));
menu.setBackground(Color.ORANGE);
menu.add(singlePlayer);
menu.add(multiPlayer);
menu.add(quit);
menu.setMaximumSize(new Dimension(164,150));
// Insert menu to the center
mainPanel.add(menu, gbc);
add(mainPanel);
}
public void singlePlayer(){
field=new Field("single player");
snake1=new Snake();
food=new Food();
setVisible(false);
removeAll();
mainPanel=field.getFieldPanel();
add(mainPanel);
//setContentPane(mainPanel);
invalidate();
validate();
setVisible(true);
Thread fieldThread=new Thread(field, "Field thread");
//fieldThread.start();
Thread snake1Thread=new Thread(snake1, "Snake thread");
//snake1Thread.start();
}
private class Mouse implements MouseListener {
#Override
public void mouseClicked(MouseEvent e) {
if(e.getSource()==quit){
System.exit(0);;
} else if(e.getSource()==singlePlayer){
singlePlayer();
} else if(e.getSource()==multiPlayer){
}
}
and here is the field class:
public class Field extends JFrame implements Runnable {
private JPanel fieldPanel;
private JPanel leftPanel;
private JPanel centralPanel;
private JPanel rightPanel;
private String type;
private JLabel leftScore,rightScore;
private int score;
private int foodX,foodY;
private JLabel [][] field;
private final int FIELD_WIDTH=50,FIELD_HEIGHT=50;
private static final long serialVersionUID = 1L;
public JPanel getFieldPanel(){return fieldPanel;}
public Field(String type){
fieldPanel=new JPanel(new GridLayout(1,3,0,0));
fieldPanel.setPreferredSize(new Dimension(700,500));
this.type=type;
// Adjust playground and score tables
leftPanel=new JPanel();
centralPanel=new JPanel();
rightPanel=new JPanel();
leftPanel.setMaximumSize(new Dimension(100,500));
leftPanel.setPreferredSize(new Dimension(100,500));
centralPanel.setMaximumSize(new Dimension(500,500));
centralPanel.setPreferredSize(new Dimension(500,500));
rightPanel.setMaximumSize(new Dimension(100,500));
rightPanel.setPreferredSize(new Dimension(100,500));
// Set leftPanel
score=0;
leftScore=new JLabel("Score:\n"+score);
leftPanel.add(leftScore);
// Adjust field
field=new JLabel[FIELD_WIDTH][FIELD_HEIGHT];
for(int i=0;i<FIELD_WIDTH;i++){
for(int j=0;j<FIELD_HEIGHT;j++){
field[i][j]=new JLabel("");
field[i][j].setSize(new Dimension(10,10));
field[i][j].setOpaque(true);
field[i][j].setBackground(Color.LIGHT_GRAY);
}
}
for(int i=0;i<FIELD_WIDTH;i++){
for(int j=0;j<FIELD_HEIGHT;j++){
if(i==0)
field[i][j].setBackground(Color.BLACK);
else if(j==0)
field[i][j].setBackground(Color.BLACK);
else if(i==FIELD_WIDTH-1)
field[i][j].setBackground(Color.BLACK);
else if(j==FIELD_HEIGHT-1)
field[i][j].setBackground(Color.BLACK);
}
}
// Adjust centralPanel
centralPanel.setLayout(new GridLayout(50,50,0,0));
for(int i=0;i<FIELD_WIDTH;i++){
for(int j=0;j<FIELD_HEIGHT;j++){
centralPanel.add(field[i][j]);
}
}
// Adjust rightPanel
rightPanel.add(new JLabel("Player 2 score: "));
fieldPanel.setLayout(new BoxLayout(fieldPanel,BoxLayout.Y_AXIS));
fieldPanel.add(leftPanel);
fieldPanel.add(centralPanel);
fieldPanel.add(rightPanel);
}
", it activates mouse listener which creates new panel,
It won't solve your problem, but don't use a MouseListener. A JButton is designed to be used with an ActionListener.
after I click "single player" is the new window with white empty background.
When creating a GUI that is designed to share the same space with multiple panels then you should be using a CardLayout to control the visible panel. Read the section from the Swing tutorial on How to Use a CardLayout for more information and examples.
Otherwise if you attempt to mange the swapping of panels manually then the basic code should be:
panel.remove(...);
panel.add(...);
panel.revalidate(); // to invoke the layout manager
panel.repaint(); // to repaint the components
Related
I will have a menu bar in which I can select multiple choices, in which will display a different JPanel for me onto my JFrame. Whenever I choose another option from my menu bar, a different JPanel will occupy the JFrame's space.
However, with this code, every time I issue the following code frame.getJPanelOne();, it creates a new JFrame, which I don't want. I only want the panel to be displayed on my existing JFrame.
Keep in mind, when my program starts, a JFrame is created from the JFrameTest class and also displays my menu bar at the top so I can select between Panel one and Panel two.
How can I successfully do this with the following code?
public class MenuActionListener implements ActionListener {
private MyFrame frame;
public MenuActionListener (MyFrame frame) {
this.frame = frame;
}
public void displayPanelOne() {
JFrameTest frame = new JFrameTest();
frame.getJPanelOne();
}
public void displayPanelTwo() {
JFrameTest frame = new JFrameTest();
frame.getJPanelTwo();
}
#Override
public void actionPerformed(final ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
//Display panel one when I select the option on the menu bar
case "Panel One":
displayPanelOne();
break;
//Display panel two when I select the option on the menu bar
case "Panel Two":
displayPanelTwo();
break;
default:
}
}
}
Here is my JFrameTest class:
public class JFrameTest extends JFrame {
private JPanel panelMain;
private JPanelOne panel1;
private JPanelTwo panel2;
private JMenuBar menuBar;
public JFrameTest() {
MenuBar menuBarInstance = new MenuBar();
frame = new JFrame();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setPreferredSize(new Dimension(720, 480));
setJMenuBar(menuBarInstance.getMenuBar());
menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));
menuBar.getMenu(0).getItem(1).addActionListener(new MenuActionListener(this));
pack();
setLocationRelativeTo(null);
setVisible(true);
panelMain = new JPanel();
panelMain.setBounds(0, 0, 420, 90);
panelMain.setPreferredSize(new Dimension(200, 40));
add(panelMain);
}
public JPanel getJPanelOne() {
panel1 = new JPanelOne();
panelMain.add(panel1);
return panelMain;
}
public JPanel getJPanelTwo() {
panel2 = new JPanelTwo();
panelMain.add(panel2);
return panelMain;
}
}
Here is both my JPanel classes in which will be added whenever I select the appropriate item from the menu bar:
public class JPanelOne extends JPanel
{
public JPanelOne()
{
// setting up black JPanel
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(220, 40));
panel.setBackground(Color.BLACK);
JLabel label = new JLabel("Panel One");
// adding button to the black JPanel
panel.add(label);
// adding blackJPanel
add(panel);
}
}
And a separate class for my other panel.
public class JPanelTwo extends JPanel
{
public JPanelTwo()
{
// setting up black JPanel
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(220, 40));
panel.setBackground(Color.RED);
JLabel label = new JLabel("Panel One");
// adding button to the black JPanel
panel.add(label);
// adding blackJPanel
add(panel);
}
}
Create menu action listener and add it to my GUI:
public class MenuBar {
private JMenuBar menuBar;
private MyFrame frame;
public MenuBar() {
System.out.println("menuBar");
//Creates a menubar for a JFrame
menuBar = new JMenuBar();
//Define addMenu items
JMenuItem addPanelOneItem = new JMenuItem("Panel One");
addPanelOneItem.setActionCommand("Panel One");
//Define addMenu items
JMenuItem addPanelTwoItem = new JMenuItem("Panel Two");
addPanelTwoItem.setActionCommand("Panel Two");
JMenu menu = new JMenu("Test");
menuBar.add(menu);
menu.add(addPanelOneItem);
menu.add(addPanelOneItem);
public JMenuBar getMenuBar()
{
return menuBar;
}
}
My question is, how can I successfully display multiple JPanel's from different classes onto my main JFrame without creating new instances of said JFrame?
Thank you in advance.
Your use case, seems perfect for CardLayout.
In card layout you can add multiple panels in the same place, but then show or hide, one panel at a time.
It's creating a new JFrame each time because you are telling it to (new JFrameTest();). Instead, do something like:-
JFrameTest frame = new JFrameTest();
public void displayPanelOne() {
// todo - remove existing panel if required?
frame.getJPanelOne();
}
your MenuActionListener class should look like this:
public class MenuActionListener implements ActionListener {
private JFrameTest frame;
public MenuActionListener(JFrameTest frame){
this.frame=frame;
}
public void displayPanelOne() {
frame.getJPanelOne();
}
public void displayPanelTwo() {
frame.getJPanelTwo();
}
#Override
public void actionPerformed(final ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
//Display panel one when I select the option on the menu bar
case "Panel One":
displayPanelOne();
break;
//Display panel two when I select the option on the menu bar
case "Panel Two":
displayPanelTwo();
break;
default:
}
}
}
and again we are missing the crucial part of the code, on which you create the MenuActionListener and add it to your GUI. if you post that code, we can solve your question. And also don't make a new question to the exact same problem as before
Copy the following code of your MenuBar
public class MenuBar {
private JMenuBar menuBar;
private MyFrame frame;
public MenuBar() {
System.out.println("menuBar");
//Creates a menubar for a JFrame
menuBar = new JMenuBar();
//Define addMenu items
JMenuItem addPanelOneItem = new JMenuItem("Panel One");
addPanelOneItem.setActionCommand("Panel One");
//Define addMenu items
JMenuItem addPanelTwoItem = new JMenuItem("Panel Two");
addPanelTwoItem.setActionCommand("Panel Two");
JMenu menu = new JMenu("Test");
menuBar.add(menu);
menu.add(addPanelOneItem);
menu.add(addPanelOneItem);
}
public JMenuBar getMenuBar()
{
return menuBar;
}
}
and in your JFrameTest class you then after
setJMenuBar(menuBarInstance.getMenuBar());
add these lines of code:
menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));
menuBar.getMenu(0).getItem(1).addActionListener(new MenuActionListener(this));
public JFrameTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setPreferredSize(new Dimension(720, 480));
menuBar=new MenuBar().getMenuBar();
menuBar.getMenu(0).getItem(0).addActionListener(new MenuActionListener(this));
menuBar.getMenu(0).getItem(1).addActionListener(new MenuActionListener(this));
pack();
setLocationRelativeTo(null);
setVisible(true);
panelMain = new JPanel();
panelMain.setBounds(0, 0, 420, 90);
panelMain.setPreferredSize(new Dimension(200, 40));
add(panelMain);
setJMenuBar(menuBar);
}
I have added buttons and text fields to a panel, but when I try to add the panel to the MenuItem nothing happens. I have defined an ActionListener for the MenuItem in which I am adding the JPanel. No error is detected by the compiler, but nothing happens when I click the MenuItem. How can I resolve this issue?
public class MenuFrame extends JFrame {
private JMenu customers;
private JMenu purchase;
private JPanel panel1 = new JPanel();
public MenuFrame() {
JButton button = new JButton();
panel1.add(button);
customers = new JMenu("Customers");
JMenuItem createInvoice = new JMenuItem("Create");
JMenuItem updateInvoice = new JMenuItem("Update");
JMenuItem deleteInvoice = new JMenuItem("Delete");
sales.add(createInvoice);
PanelHandler p = new PanelHandler(panel1);
createInvoice.addActionListener(p);
}
private class PanelHandler implements ActionListener {
private JPanel panel;
public PanelHandler(JPanel p) {
this.panel = p;
}
public void actionPerformed(ActionEvent e) {
// getContentPane().removeAll();
// getContentPane().setVisible(true);
// JButton b=new JButton("Enter");
// panel.add(b);
panel.setVisible(true);
add(panel, BorderLayout.SOUTH);
getContentPane().doLayout();
// update(getGraphics());
}
}
}
Don't invoke doLayout() directly.
When add (or remove) components from a visible GUI the basic code is:
panel.add(...);
panel.realidate(); // to invoke the layout manager
panel.repaint(); to repaint components
I'm currently self-studying Java. I'm learning Graphical User Interface(GUI) programming.
I want JPanels to be arranged from top to bottom in a JFrame.First of all,I have a JLabel added to the first JPanel. The second JPanel has 5 JRadioButtions. The third JPanel has a JButton and a JLabel.
When the JButton is pressed,the JLabel in the 3rd JPanel shows some text.
I used BoxLayout(BoxLayout.X_AXIS) for all the JPanels and added all 3 of them into a JFrame which has FlowLayout(). Here is a small piece of code:
class GUI extends JFrame implements ActionListener {
JPanel pan1,pan2,pan3; //3 JPanels
JRadioButton rad1,rad2,rad3,rad4,rad5; //5 RadioButtons
JButton button; //A JButton
JLabel label; //A JLabel
public GUI(String header)
{
super(header);
setLayout(new FlowLayout()); //set FlowLayout to JFrame
setBounds(350,325,600,125);
setResizable(false);
creator();
adder();
commander();
add(pan1);
add(pan2);
add(pan3); //Add all 3 panels to JFrame
}
private void adder()
{
pan1.setLayout(new BoxLayout(pan1,BoxLayout.X_AXIS));
pan2.setLayout(new BoxLayout(pan2,BoxLayout.X_AXIS));
pan3.setLayout(new BoxLayout(pan3,BoxLayout.X_AXIS)); //Layout for all 3 JPanels
pan1.add(new JLabel("Choose a Security Level"));
ButtonGroup group=new ButtonGroup();
group.add(rad1);
group.add(rad2);
group.add(rad3);
group.add(rad4);
group.add(rad5);
pan2.add(rad1);
pan2.add(rad2);
pan2.add(rad3);
pan2.add(rad4);
pan2.add(rad5);
pan3.add(button);
pan3.add(label);
}
private void creator()
{
pan1=new JPanel();
pan2=new JPanel();
pan3=new JPanel();
rad1=new JRadioButton("Security Level 1");
rad2=new JRadioButton("Security Level 2");
rad3=new JRadioButton("Security Level 3");
rad4=new JRadioButton("Security Level 4");
rad5=new JRadioButton("Security Level 5");
button=new JButton("Move On");
label=new JLabel();
}
private void commander()
{
rad1.addActionListener(this);
rad2.addActionListener(this);
rad3.addActionListener(this);
rad4.addActionListener(this);
rad5.addActionListener(this);
rad1.setActionCommand("radio1");
rad2.setActionCommand("radio2");
rad3.setActionCommand("radio3");
rad4.setActionCommand("radio4");
rad5.setActionCommand("radio5");
button.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
//When button is pressed,the text in label changes
if(evt.getActionCommand().equals("radio1"))
label.setText("Very Easy to bypass");
else if(evt.getActionCommand().equals("radio2"))
label.setText("Easy to bypass");
else if(evt.getActionCommand().equals("radio3"))
label.setText("Can bypass Sometimes");
else if(evt.getActionCommand().equals("radio4"))
label.setText("Hard to bypass");
else if(evt.getActionCommand().equals("radio5"))
label.setText("Very Hard to bypass");
else
{ //Code here
}
repaint();
//More code here....
}
}
This is the output I'm getting when I select the first radiobutton(Forget the green colour):
I want the "Very easy to Bypass" text to be placed above the "Move on" button and below all the JRadioButtons. I can increase the size of the JFrame so that there will be enough space. My questions are:
Which Layout should I use to achieve this?
Should this layout be applied just for the JFrame or all 3 JPanels?
you must use GridLayout
Its very easy to use it, just add it like this. Take care of the import commands. :)
JFrame frame = new JFrame(new GridLayout(3,5));
Use GridLayout
GridLayout layout = new GridLayout(0, 1, 0, 5);
setLayout(layout);
What I would do to add 5 JPanels:
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class PanelAdd extends JFrame {
JPanel [] panels ;
public PanelAdd() {
GridLayout layout = new GridLayout(0, 1, 0, 5);
setLayout(layout);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setSize(400, 350);
}
public static void main(String [] args) {
PanelAdd add = new PanelAdd();
add.addPanels();
add.setVisible(true);
}
private void addPanels() {
panels = new JPanel[5];
for (int i = 0 ; i < panels.length ; i++) {
panels[i] = new JPanel();
panels[i].add(new JLabel("This Is Panel "+i));
add(panels[i]);
}
}
}
In this example, I made an array of 5 JPanels and add them through a loop.
I used GridLayout for the job.
This is just a hint for your answer
when you call add method from jframe,you can also give specified position to your panel in frame
like this:
JPanel pan1,pan2,pan3; //3 JPanels
JRadioButton rad1,rad2,rad3,rad4,rad5; //5 RadioButtons
JButton button; //A JButton
JLabel label; //A JLabel
public GUI(String header)
{
super(header);
setLayout(new FlowLayout()); //set FlowLayout to JFrame
setBounds(350,325,600,125);
setResizable(false);
creator();
adder();
commander();
add(pan1,BorderLayout.NORTH);
add(pan2,BorderLayout.CENTER);
add(pan3,,BorderLayout.SOUTH); //Add all panels to JFrame
}
good luck
I have an internal frame which has my customer JPanel. In my customer JPanel, I added two panels which is from the outside source.
One of these has button to close the panel. However when I clicked it, it is no effect. How can I make the action listener on the button?
public class MyInternalFrame extends JInternalFrame{
private PDFJPanel panel=null;
public MyInternalFrame(File file) {
super("Test" + file.getName(), true, true, true, true);
panel=new PDFJPanel(file);
this.add(panel, BorderLayout.CENTER);
}
}
There is my customer JPanel
public class PDFJPanel extends JPanel {
private JPanel jpAnnotation=null;
private JScrollPane scrollPane = new JScrollPane();
private File thisFile=null;
private PDFNotesBean bean=null;
private CommentPanel commentPane=null;
public PDFJPanel(File file) {
thisFile=file;
getJPanel();
}
public void getJPanel() {
this.setLayout(new BorderLayout());
this.add(getPDFNotesBean(), BorderLayout.CENTER);
commentPane= bean.getCommentPanel();
bean.getCommentPanelNotes().getjcbHideComments().setVisible(false);
//this code can get the button
bean.getCommentPanelNotes().getToolbar().getCloseButton();
//Right size of the Panel
JPanel rightPanel=new JPanel();
rightPanel.setLayout(new BorderLayout());
rightPanel.setBackground(Color.GREEN);
jpAnnotation=new JPanel();
JButton btnUnderline =new JButton(new ImageIcon ("../UnderlineIcon.gif"));
btnUnderline.setSize(50, 260);
btnUnderline.setAlignmentX(JButton.LEFT_ALIGNMENT);
jpAnnotation.add(btnUnderline);
rightPanel.add(jpAnnotation, BorderLayout.NORTH );
rightPanel.add((Component) commentPane, BorderLayout.CENTER );
this.add(rightPanel, BorderLayout.EAST );
}
}
I'll take a shot in the dark.
jpAnnotation.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
JFrame myInternalFrame= (JFrame)SwingUtilities.getWindowAncestor(this);
myInternalFrame.remove(PDFJPanel.this);
myInternalFrame.invalidate();
myInternalFrame.validate();
myInternalFrame.repaint();
}
});
I'm writing my first GUI program that actually does something and I am having problems with the action listener. The program when complete will take a double input and make conversions from one unit to another based on some radio button selections which i haven't added yet. The problem right now is the Action listener doesn't recognize my text fields.
I have an input text field and an output text fields in separate panels. I created an action listener and I added the input text field to the listener.
ActionListener handler = new HandlerClass();
textField.addActionListener(handler);
then I created an in class definition for the handler class but when I write the action preformed method textField and output cannot be resolved by the program. Can anyone see what I'm doing wrong?
public class conversionDisplay extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel northPanel;
private JPanel southPanel;
private JPanel eastPanel;
private JPanel westPanel;
public conversionDisplay() {
super("Temperature Conversion");
northPanel = new JPanel(); //create northPanel
northPanel.setLayout(new GridLayout(1,2,5,5));
northPanel.add(new JPanel());
JPanel northLabelPanel = new JPanel(new BorderLayout()) ;
northLabelPanel.add(new JLabel("Input"), BorderLayout.EAST);
northPanel.add(northLabelPanel);
JTextField textField =new JTextField(10);
northPanel.add(textField);
northPanel.add(new JPanel());
southPanel = new JPanel(); //create southPanel
southPanel.setLayout(new GridLayout(1,2));
southPanel.add(new JPanel());
JPanel southLabelPanel = new JPanel(new BorderLayout());
southLabelPanel.add(new JLabel("Output "), BorderLayout.EAST);
southPanel.add(southLabelPanel);
JTextField output;
southPanel.add(output = new JTextField( 10));
output.setEditable(false);
southPanel.add(new JPanel());
add(northPanel,BorderLayout.NORTH); //add north panel
add(southPanel,BorderLayout.SOUTH); //add north panel
ActionListener handler = new HandlerClass();
textField.addActionListener(handler);
setSize(350, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private class HandlerClass implements ActionListener{
public void actionPerformed(ActionEvent e) {
double input = textField.getText();
if (input != 0)
{
output.setText(input); //Perform conversion
}
}
}
}
Your textField JTextField is declared inside of a constructor and is thus only visible within that block (again the constructor). You need to make it an instance field of the class.
i.e.,
public class Foo {
private Bar bar = new Bar(); // this field is visible throughout the object
public Foo() {
Baz baz = new Baz(); // this is only visible within this constructor
}
So just like the bar variable above is visible while the baz variable that is declared in the constructor is not, you'll want to move your JTextField variable declarations out of the constructor.
you must parse String to Double value
public void actionPerformed(ActionEvent e) {
double input = Double.parseDouble(textField.getText());
if (input != 0)
{
output.setText(input+""); //Perform conversion
}
}
and declare JTextField output,textField as Globel.
public class conversionDisplay extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel northPanel;
private JPanel southPanel;
private JPanel eastPanel;
private JPanel westPanel;
JTextField output = new JTextField(10);
public conversionDisplay() {
super("Temperature Conversion");