I want to make a JFrame containing two JPanels thanks to a Layout. On the left is the result (despite the setExtendedState(JFrame.MAXIMIZED_BOTH);) and on the right when I resize the frame:
Screen of the result
Here is the minimalized code:
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* The Frame which will contain one or two Panels.
*
*/
class Frame extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel panAction;
public void JFrame() {
setLayout(new GridBagLayout());
GridBagConstraints info = new GridBagConstraints();
info.gridx = info.gridy = 0;
//info.gridwidth = 1;
//info.gridheight = 2;
info.fill = GridBagConstraints.BOTH;
//info.weightx = 1;
//info.weighty = 1;
JPanel buttonPanel = new ButtonPanel(this);
add(buttonPanel, info);
setExtendedState(JFrame.MAXIMIZED_BOTH);
pack();
}
public void changeSecondPanel(JPanel panel) {
if(this.panAction != null) {
remove(this.panAction);
}
GridBagConstraints info = new GridBagConstraints();
info.gridx = 0;
info.gridy = 1;
//info.gridwidth = 1;
//info.gridheight = 2;
//info.weightx = 1;
//info.weighty = 1;
info.fill = GridBagConstraints.BOTH;
add(panAction, info);
this.panAction = panel;
}
}
/**
* The upper Panel.
*
*/
class ButtonPanel extends JPanel {
private static final long serialVersionUID = 1L;
public ButtonPanel(final Frame frame) {
setBackground(Color.BLUE);
JButton button = new JButton("CREATE");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
frame.changeSecondPanel(
/**
* The bottom Panel.
*/
new JPanel() {
private static final long serialVersionUID = 1L;
{
setBackground(Color.GREEN);
}
});
}
});
}
}
public class PanelProblem {
public static void main(String[] args) {
new Frame().setVisible(true);
}
}
I tried GridLayout and BorderLayout but it didn't solve my problem. I already checked Can components of a gridbaglayout fill parent frame upon resize?, GridBagLayout doesn't fill all the space and many other sources.
The void method named JFrame looks suspicious.
public void JFrame() { ... }
I think you intended to write a constructor like
public Frame() { ... }
The layout code that you wrote is not being called. This fix would solve that problem.
Hope this helps.
Related
The idea is to have one "global" JFrame which I can then add/remove JPanels as needed to make a smooth flowing application. Currently, when I try changing from the first JPanel to the second, the second won't display. My code is below:
Handler (class to run the app):
package com.example.Startup;
import com.example.Global.Global_Frame;
public class Handler
{
public Handler()
{
gf = new Global_Frame();
gf.getAccNum();
gf.setVisible(true);
}
public static void main(String[] args)
{
new Handler();
}
Global_Frame gf = null;
}
public static void main(String[] args)
{
new Handler();
}
Global_Vars gv = null;
Global_Frame gf = null;
}
Global Frame:
package com.example.Global;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import com.example.FirstRun.AccDetails;
import com.example.FirstRun.FirstTimeRun;
public class Global_Frame extends JFrame
{
private static final long serialVersionUID = 1L;
ActionListener val = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
getUserDetails();
}
};
public Global_Frame()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // get look and feel based on OS
}
catch (ClassNotFoundException ex) // catch all errors that may occur
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (InstantiationException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (UnsupportedLookAndFeelException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
EventQueue.invokeLater(new Runnable()
{
public void run() //run the class's constructor, therefore starting the UI being built
{
initComponents();
}
});
}
public void initComponents()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
revalidate(); // revalidate the elements that will be displayed
repaint(); // repainting what is displayed if going coming from a different form
pack(); // packaging everything up to use
setLocationRelativeTo(null); // setting form position central
}
public void getAccNum()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
FirstTimeRun panel1 = new FirstTimeRun(val);
add(panel1);
revalidate();
repaint();
pack();
}
public void getUserDetails()
{
getContentPane().removeAll();
resizing(750, 500);
AccDetails panel2 = new AccDetails();
add(panel2);
revalidate();
repaint();
pack();
}
private void resizing(int width, int height)
{
timer = new Timer (10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0)
{
getContentPane().removeAll();
setPreferredSize(new Dimension(sizeW, sizeH));
revalidate();
repaint();
pack();
if (!wToggle)
sizeW += 2;
if (!hToggle)
sizeH += 2;
if (toggle)
{
setLocationRelativeTo(null);
toggle = false;
}
else
toggle = true;
if (sizeW == width)
wToggle = true;
if (sizeH == height)
hToggle = true;
if (hToggle && wToggle)
timer.stop();
}
});
timer.start();
}
//variables used for window resizing
private Timer timer;
private int sizeW = 600;
private int sizeH = 400;
private boolean toggle = false;
private boolean wToggle = false;
private boolean hToggle = false;
public int accNum = 0;
}
First Panel:
package com.example.FirstRun;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class FirstTimeRun extends JPanel
{
private static final long serialVersionUID = 1L;
public FirstTimeRun()
{
}
public FirstTimeRun(ActionListener val)
{
initComponents(val);
}
private void initComponents(ActionListener val) // method to build initial view for user for installation
{
pnlStart = new JPanel[1];
btnNext = new JButton();
pnlStart[0] = new JPanel();
btnNext.setText("Next"); // adding text to button for starting
btnNext.setPreferredSize(new Dimension(80, 35)); //positioning start button
btnNext.addActionListener(val);
pnlStart[0].add(btnNext); // adding button to JFrame
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlStart[0]);
}
// objects used in UI
private JPanel[] pnlStart;
private JButton btnNext;
}
Second Panel:
package com.example.FirstRun;
import java.awt.BorderLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AccDetails extends JPanel
{
private static final long serialVersionUID = 1L;
public AccDetails()
{
accAssets();
}
private void accAssets()
{
// instantiating elements of the GUI
pnlAccDetails = new JPanel[2];
lblWelcome = new JLabel();
lblMain = new JLabel();
for (int i = 0; i < 2; i++)
pnlAccDetails[i] = new JPanel();
lblWelcome.setText("Welcome to Example_App"); // label welcoming user
pnlAccDetails[0].setLayout(new BoxLayout(pnlAccDetails[0], BoxLayout.LINE_AXIS));
pnlAccDetails[0].add(lblWelcome); // adding label to form
lblMain.setText("<html>The following information that is collected will be used as part of the Example_App process to ensure that each user has unique Example_App paths. Please fill in all areas of the following tabs:</html>"); // main label that explains what happens, html used for formatting
pnlAccDetails[1].setLayout(new BorderLayout());
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_START);
pnlAccDetails[1].add(lblMain, BorderLayout.CENTER); //adding label to JFrame
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_END);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlAccDetails[0]);
add(pnlAccDetails[1]);
}
private JLabel lblWelcome;
private JLabel lblMain;
private JPanel[] pnlAccDetails;
}
I have tried using both a CardLayout and the "revalidate();" "repaint();" and "pack();" options and I'm stumped as to why it's not showing. Thanks in advance for any help that can be offered.
EDIT:
While cutting down my code, if the "resizing" method is removed, the objects are shown when the panels change. I would like to avoid having to remove this completely as it's a smooth transition for changing the JFrame size.
#John smith it is basic example of switch from one panel to other panel I hope this will help you to sort out your problem
Code:
package stack;
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.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class RemoveAndAddPanel implements ActionListener{
JFrame frame;
JPanel firstPanel;
JPanel secondPanel;
JPanel controlPanel;
JButton nextButton;
public RemoveAndAddPanel() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firstPanel = new JPanel();
firstPanel.add(new JLabel("FirstPanel"));
firstPanel.setPreferredSize(new Dimension(100,100));
secondPanel = new JPanel();
secondPanel.add(new JLabel("Second panel"));
secondPanel.setPreferredSize(new Dimension(100,100));
nextButton = new JButton("Next panel");
controlPanel = new JPanel();
nextButton.addActionListener(this);
controlPanel.add(nextButton);
frame.setLayout(new BorderLayout());
frame.add(firstPanel,BorderLayout.CENTER);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.setVisible(true);
frame.setSize(300,100);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == nextButton) {
frame.remove(firstPanel);
frame.add(secondPanel);
nextButton.setEnabled(false);
}
frame.validate();
}
public static void main(String args[]) {
new RemoveAndAddPanel();
}
}
As mentioned in the edit, the problem lay within the resizing method. When the timer stopped, it wouldn't go anywhere, causing the UI to not load. The fix to the code is clearing the screen and adding the call to resizing to the actionlistener. Then adding a call to the next method after:
timer.stop();
Thanks for getting me to remove the mess around it and find the source of the problem #matt & #Hovercraft Full of Eels upvotes for both of you.
The main thing to consider while changing panel in a jframe is the layout, for a body(main) panel to change to any other panel the parent panel must be of type CardLayout body.setLayout(new java.awt.CardLayout());
After that you can now easily switch between panels wiht the sample code below
private void updateViewLayout(final HomeUI UI, final JPanel paneeelee){
final JPanel body = UI.getBody(); //this is the JFrame body panel and must be of type cardLayout
System.out.println("Page Loader Changing View");
new SwingWorker<Object, Object>() {
#Override
protected Object doInBackground() throws Exception {
body.removeAll();//remove all visible panel before
body.add(paneeelee);
body.revalidate();
body.repaint();
return null;
}
#Override
protected void done() {
UI.getLoader().setVisible(false);
}
}.execute();
}
I am creating a simple app that codify a text but i am struggling with some ActionListeners. When I'm choosing something from JComboBox there must happen things (if you choose Caesar's Cipher, an offset must appear, if you choose Beaufort, the offset will dissapper; the offset is a JTextField) and according to the choose the execute button will get the according ActionListener implementation. The thing is, When I'm choosing the Caesar's Cipher nothing happens, even if i add CaesarsCipher that implements ActionListener to codify the text, nothing will work.
MyFrame.java
package cipher;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
#SuppressWarnings("serial")
class MyFrame extends JFrame {
private JButton executeButton;
private ComboBoxPanel leftPanel;
private TextPanel rightPanel;
public MyFrame(String title) {
super(title);
//Initiate the frame
initFrame();
//Initiate the button that need to be pressed to execute a cipher
initButton();
//Init the panels
initPanel();
//Pack everything together;
packing();
//Make the frame visible to the user
setVisible(true);
}
//////////PACKING EVERYTHING TOGETHER//////////
private void packing() {
add(executeButton,BorderLayout.SOUTH);
add(leftPanel, BorderLayout.WEST);
add(rightPanel, BorderLayout.EAST);
}
//////////INITIATING THE FRAME WITH ALL COMPONENTS//////////
private void initPanel() {
leftPanel = new ComboBoxPanel();
rightPanel = new TextPanel();
}
private void initButton() {
executeButton = new JButton("Execute cipher");
}
private void initFrame() {
setSize(800,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new BorderLayout());
setResizable(false);
}
//////////HIDE THE OFFSET WHEN CHOOSING ALGORITHMS THAT DO NOT REQUIRE OFFSET//////////
public void hideOffset() {
leftPanel.hideOffset();
}
public void showOffset() {
leftPanel.showOffset();
}
//////////UPDATE LEFT PANEL AFTER HIDING OFFSET//////////
public void updateLeftPanel() {
leftPanel.updatePanel();
}
//////////LISTENERS//////////
/////COMBO BOX/////
public void addComboBoxListener(ActionListener comboBoxListener) {
leftPanel.addComboBoxListener(comboBoxListener);
}
/////EXECUTE BUTTON/////
public void addExecuteButtonListener(ActionListener executeButtonListener) {
executeButton.addActionListener(executeButtonListener);
}
//////////GETTERS//////////
/////OFFSET GETTER/////
public Integer getOffset() {
return Integer.parseInt(leftPanel.getOffset());
}
/////INPUT GETTER/////
public String getInputText() {
return rightPanel.getInputText();
}
//////////SETTERS//////////
/////OUTPUT TEXT SETTER/////
public void setOutputText(String text) {
rightPanel.setOutputText(text);
}
}
ComboBoxPanel.java
package cipher;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.Border;
#SuppressWarnings("serial")
class ComboBoxPanel extends JPanel {
private final String []CIPHERS = {"Caesar's Cipher", "ROT13", "Beaufort Cipher", "Autokey Cipher"};
#SuppressWarnings("rawtypes")
private JComboBox comboCiphers;
private JTextField offset;
public ComboBoxPanel() {
initSize();
initComboBox();
initBorder();
initLayout();
initTextField();
packing();
}
private void initTextField() {
offset = new JTextField(10);
}
private void initLayout() {
setLayout(new GridBagLayout());
}
private void packing() {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 10;
add(comboCiphers,gbc);
gbc.gridy = 1;
add(offset,gbc);
}
private void initBorder() {
Border outer = BorderFactory.createEmptyBorder(5, 5, 5, 5);
Border inner = BorderFactory.createTitledBorder("Choose the cipher");
setBorder(BorderFactory.createCompoundBorder(outer, inner));
}
#SuppressWarnings({ "unchecked", "rawtypes" })
private void initComboBox() {
comboCiphers = new JComboBox(CIPHERS);
}
//Remainder: delete this, let the layout to do its job.
private void initSize() {
Dimension size = getPreferredSize();
size.width = 390;
setPreferredSize(size);
}
public void hideOffset() {
offset.setVisible(false);
}
public void showOffset() {
offset.setVisible(true);
}
public void updatePanel() {
revalidate();
repaint();
}
public void addComboBoxListener(ActionListener comboBoxListener) {
comboCiphers.addActionListener(comboBoxListener);
}
public String getOffset() {
return offset.toString();
}
}
TextPanel.java
package cipher;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
#SuppressWarnings("serial")
class TextPanel extends JPanel {
private JTextArea inputArea, outputArea;
private JScrollPane inputScroll, outputScroll;
public TextPanel() {
//////////PANEL METHODS///////
/*
//Initiate the size of the panel
initSize();
*/
//Initiate the border of the entire panel
initBorder();
//Setup the layout of the panel
initLayout();
//////////TEXT AREAS METHODS///////
//Initiate the text areas
initTextArea();
//Initiate the borders for the 2 text areas
initTextAreaBorder();
//Create scrolls for both text areas
initScrollPane();
//Pack everything together
packing();
}
private void packing() {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(inputScroll,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 1;
gbc.weighty = 1;
add(outputScroll,gbc);
}
private void initScrollPane() {
inputScroll = new JScrollPane(inputArea);
outputScroll = new JScrollPane(outputArea);
}
private void initTextAreaBorder() {
inputArea.setBorder(new LineBorder(Color.black));
outputArea.setBorder(new LineBorder(Color.black));
}
private void initBorder() {
Border outer = BorderFactory.createEmptyBorder(5, 5, 5, 5);
Border inner = BorderFactory.createTitledBorder("Text");
setBorder(BorderFactory.createCompoundBorder(outer,inner));
}
private void initLayout() {
setLayout(new GridBagLayout());
}
private void initTextArea() {
inputArea = new JTextArea(10,77);
outputArea = new JTextArea(10,77);
outputArea.append("Output...");
outputArea.setEditable(false);
}
public void addComboBoxListener(ActionListener comboBoxListener) {
//.addActionListener(comboBoxListener);
}
/*private void initSize() {
//setPreferredSize sets the minimum
Dimension size = getPreferredSize();
size.width = 390;
setPreferredSize(size);
}*/
public String getInputText() {
return inputArea.toString();
}
public void setOutputText(String text) {
outputArea.append(text);
}
}
ApplicationController.java
package cipher;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
public class ApplicationController{
private MyFrame frame;
public ApplicationController(MyFrame frame) {
this.frame = frame;
this.frame.addComboBoxListener(new ComboBoxListener());
}
class ComboBoxListener implements ActionListener {
#SuppressWarnings("rawtypes")
#Override
public void actionPerformed(ActionEvent e) {
JComboBox c = (JComboBox) e.getSource();
String selected = c.getSelectedItem().toString();
if(selected.equalsIgnoreCase("Caesar's Cipher")) {
frame.addExecuteButtonListener(new CaesarsCipher());
frame.showOffset();
frame.updateLeftPanel();
} else if(selected.equalsIgnoreCase("ROT13")) {
frame.showOffset();
frame.updateLeftPanel();
} else if(selected.equalsIgnoreCase("Beaufort Cipher")) {
frame.hideOffset();
frame.updateLeftPanel();
} else if(selected.equalsIgnoreCase("Autokey Cipher")) {
frame.hideOffset();
frame.updateLeftPanel();
}
}
}
class CaesarsCipher implements ActionListener {
public void actionPerformed(ActionEvent e) {
int offset = frame.getOffset();
char []text = frame.getInputText().toCharArray();
for(int i = 0 ; i < text.length ; i++) {
text[i] = (char)(((int)text[i] + offset) % 26);
}
String newText = new String(text);
frame.setOutputText(newText);
}
}
}
Please someone explain what is wrong. I am ready to learn from mistakes. Thanks.
You didn't create an instance of your applicationController so your comboBox Listener was never created.
In the future, you should not be extending JFrame. All you need is an instance of it. You have also added complexity by putting in those extra add listener methods.
The idea is to have one "global" JFrame which I can then add/remove JPanels as needed to make a smooth flowing application. Currently, when I try changing from the first JPanel to the second, the second won't display. My code is below:
Handler (class to run the app):
package com.example.Startup;
import com.example.Global.Global_Frame;
public class Handler
{
public Handler()
{
gf = new Global_Frame();
gf.getAccNum();
gf.setVisible(true);
}
public static void main(String[] args)
{
new Handler();
}
Global_Frame gf = null;
}
public static void main(String[] args)
{
new Handler();
}
Global_Vars gv = null;
Global_Frame gf = null;
}
Global Frame:
package com.example.Global;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import com.example.FirstRun.AccDetails;
import com.example.FirstRun.FirstTimeRun;
public class Global_Frame extends JFrame
{
private static final long serialVersionUID = 1L;
ActionListener val = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
getUserDetails();
}
};
public Global_Frame()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // get look and feel based on OS
}
catch (ClassNotFoundException ex) // catch all errors that may occur
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (InstantiationException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IllegalAccessException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
catch (UnsupportedLookAndFeelException ex)
{
Logger.getLogger(Global_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
EventQueue.invokeLater(new Runnable()
{
public void run() //run the class's constructor, therefore starting the UI being built
{
initComponents();
}
});
}
public void initComponents()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
revalidate(); // revalidate the elements that will be displayed
repaint(); // repainting what is displayed if going coming from a different form
pack(); // packaging everything up to use
setLocationRelativeTo(null); // setting form position central
}
public void getAccNum()
{
setPreferredSize(new Dimension(600, 400)); // setting measurements of jframe
FirstTimeRun panel1 = new FirstTimeRun(val);
add(panel1);
revalidate();
repaint();
pack();
}
public void getUserDetails()
{
getContentPane().removeAll();
resizing(750, 500);
AccDetails panel2 = new AccDetails();
add(panel2);
revalidate();
repaint();
pack();
}
private void resizing(int width, int height)
{
timer = new Timer (10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0)
{
getContentPane().removeAll();
setPreferredSize(new Dimension(sizeW, sizeH));
revalidate();
repaint();
pack();
if (!wToggle)
sizeW += 2;
if (!hToggle)
sizeH += 2;
if (toggle)
{
setLocationRelativeTo(null);
toggle = false;
}
else
toggle = true;
if (sizeW == width)
wToggle = true;
if (sizeH == height)
hToggle = true;
if (hToggle && wToggle)
timer.stop();
}
});
timer.start();
}
//variables used for window resizing
private Timer timer;
private int sizeW = 600;
private int sizeH = 400;
private boolean toggle = false;
private boolean wToggle = false;
private boolean hToggle = false;
public int accNum = 0;
}
First Panel:
package com.example.FirstRun;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
public class FirstTimeRun extends JPanel
{
private static final long serialVersionUID = 1L;
public FirstTimeRun()
{
}
public FirstTimeRun(ActionListener val)
{
initComponents(val);
}
private void initComponents(ActionListener val) // method to build initial view for user for installation
{
pnlStart = new JPanel[1];
btnNext = new JButton();
pnlStart[0] = new JPanel();
btnNext.setText("Next"); // adding text to button for starting
btnNext.setPreferredSize(new Dimension(80, 35)); //positioning start button
btnNext.addActionListener(val);
pnlStart[0].add(btnNext); // adding button to JFrame
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlStart[0]);
}
// objects used in UI
private JPanel[] pnlStart;
private JButton btnNext;
}
Second Panel:
package com.example.FirstRun;
import java.awt.BorderLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class AccDetails extends JPanel
{
private static final long serialVersionUID = 1L;
public AccDetails()
{
accAssets();
}
private void accAssets()
{
// instantiating elements of the GUI
pnlAccDetails = new JPanel[2];
lblWelcome = new JLabel();
lblMain = new JLabel();
for (int i = 0; i < 2; i++)
pnlAccDetails[i] = new JPanel();
lblWelcome.setText("Welcome to Example_App"); // label welcoming user
pnlAccDetails[0].setLayout(new BoxLayout(pnlAccDetails[0], BoxLayout.LINE_AXIS));
pnlAccDetails[0].add(lblWelcome); // adding label to form
lblMain.setText("<html>The following information that is collected will be used as part of the Example_App process to ensure that each user has unique Example_App paths. Please fill in all areas of the following tabs:</html>"); // main label that explains what happens, html used for formatting
pnlAccDetails[1].setLayout(new BorderLayout());
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_START);
pnlAccDetails[1].add(lblMain, BorderLayout.CENTER); //adding label to JFrame
pnlAccDetails[1].add(Box.createHorizontalStrut(20), BorderLayout.LINE_END);
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(pnlAccDetails[0]);
add(pnlAccDetails[1]);
}
private JLabel lblWelcome;
private JLabel lblMain;
private JPanel[] pnlAccDetails;
}
I have tried using both a CardLayout and the "revalidate();" "repaint();" and "pack();" options and I'm stumped as to why it's not showing. Thanks in advance for any help that can be offered.
EDIT:
While cutting down my code, if the "resizing" method is removed, the objects are shown when the panels change. I would like to avoid having to remove this completely as it's a smooth transition for changing the JFrame size.
#John smith it is basic example of switch from one panel to other panel I hope this will help you to sort out your problem
Code:
package stack;
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.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class RemoveAndAddPanel implements ActionListener{
JFrame frame;
JPanel firstPanel;
JPanel secondPanel;
JPanel controlPanel;
JButton nextButton;
public RemoveAndAddPanel() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firstPanel = new JPanel();
firstPanel.add(new JLabel("FirstPanel"));
firstPanel.setPreferredSize(new Dimension(100,100));
secondPanel = new JPanel();
secondPanel.add(new JLabel("Second panel"));
secondPanel.setPreferredSize(new Dimension(100,100));
nextButton = new JButton("Next panel");
controlPanel = new JPanel();
nextButton.addActionListener(this);
controlPanel.add(nextButton);
frame.setLayout(new BorderLayout());
frame.add(firstPanel,BorderLayout.CENTER);
frame.add(controlPanel, BorderLayout.SOUTH);
frame.setVisible(true);
frame.setSize(300,100);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == nextButton) {
frame.remove(firstPanel);
frame.add(secondPanel);
nextButton.setEnabled(false);
}
frame.validate();
}
public static void main(String args[]) {
new RemoveAndAddPanel();
}
}
As mentioned in the edit, the problem lay within the resizing method. When the timer stopped, it wouldn't go anywhere, causing the UI to not load. The fix to the code is clearing the screen and adding the call to resizing to the actionlistener. Then adding a call to the next method after:
timer.stop();
Thanks for getting me to remove the mess around it and find the source of the problem #matt & #Hovercraft Full of Eels upvotes for both of you.
The main thing to consider while changing panel in a jframe is the layout, for a body(main) panel to change to any other panel the parent panel must be of type CardLayout body.setLayout(new java.awt.CardLayout());
After that you can now easily switch between panels wiht the sample code below
private void updateViewLayout(final HomeUI UI, final JPanel paneeelee){
final JPanel body = UI.getBody(); //this is the JFrame body panel and must be of type cardLayout
System.out.println("Page Loader Changing View");
new SwingWorker<Object, Object>() {
#Override
protected Object doInBackground() throws Exception {
body.removeAll();//remove all visible panel before
body.add(paneeelee);
body.revalidate();
body.repaint();
return null;
}
#Override
protected void done() {
UI.getLoader().setVisible(false);
}
}.execute();
}
I have a grid layout that is 9x9 and generates Jtextareas to fill it. If the user presses a button i want the grid layout to become empty again so i can refill it again but with no relation to what it previously was filled with.
is there some sort of command like gridlayout.delete() or something?
I'm guessing that you want to clear the text components that are held by the GridLayout-using container (you don't tell us, and please understand that this is key information about your question). If so, put them into a collection such as an ArrayList and iterate through the list calling setText("") within the loop.
If you're using Java 8, then this "for loop" can be replaced with a forEach(...) call on a Stream. For example, if you have an ArrayList like so:
List<JTextComponent> textComponentList = new ArrayList<>();
Then you can clear all the text components it holds with this call:
textComponentList.stream().forEach(tc -> tc.setText(""));
For example:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.text.JTextComponent;
#SuppressWarnings("serial")
public class ClearGrid extends JPanel {
private static final int ROWS = 9;
private static final int COLS = ROWS;
private static final int GAP = 2;
private static final Font FONT = new Font(Font.SANS_SERIF, Font.BOLD, 32);
private static final int FIELD_COLS = 2;
List<JTextComponent> textComponentList = new ArrayList<>();
public ClearGrid() {
JPanel gridPanel = new JPanel(new GridLayout(ROWS, COLS, GAP, GAP));
gridPanel.setBackground(Color.BLACK);
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
JTextField textField = new JTextField(FIELD_COLS);
textField.setFont(FONT);
textField.setHorizontalAlignment(JTextField.CENTER);
textComponentList.add(textField);
gridPanel.add(textField);
}
}
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new ClearAllAction("Clear All", KeyEvent.VK_C)));
setLayout(new BorderLayout());
add(gridPanel);
add(buttonPanel, BorderLayout.PAGE_END);
}
private class ClearAllAction extends AbstractAction {
public ClearAllAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
textComponentList.stream().forEach(tc -> tc.setText(""));
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("ClearGrid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ClearGrid());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
I've made a JFrame with two JPanels aligned within it, one with a width of 750 pixels and the other with a width of 250 pixels. So far that's worked fine. Next I wanted to add some JTextFields to the panel on the right, so I included them in the constructor. Now when I try to run the code the textfields are positioned in the centre of the other panel, and aren't fully expanded until something is typed in them (they look like thin white strips). I haven't set any layouts at the moment as I just want to draw the textfields initially and arrange them later, only I do want them to be in the correct panel. Why isn't this working?
Main class:
package forces;
import java.awt.BorderLayout;
import javax.swing.*;
public class PrimaryWindow extends JFrame{
private static final long serialVersionUID = 1L;
JFrame frame;
ForcePanel panel;
DataPanel dpanel;
public PrimaryWindow()
{
frame = new JFrame("Forces");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(1000,800);
frame.setResizable(false);
panel = new ForcePanel();
frame.add(panel);
dpanel = new DataPanel();
frame.add(dpanel);
frame.setVisible(true);
}
public static void main(String args[])
{
new PrimaryWindow();
}
}
Panel 1 (this is the 750 pixel panel):
package forces;
import javax.swing.*;
import java.awt.*;
public class ForcePanel extends JPanel {
boolean simulate = false;
private static final long serialVersionUID = 1L;
public ForcePanel()
{
this.setSize(750,800);
this.setBackground(Color.BLACK);
}
}
Panel 2 (where the text fields should be):
package forces;
import javax.swing.*;
import java.awt.Color;
import java.awt.BorderLayout;
public class DataPanel extends JPanel {
private static final long serialVersionUID = 1L;
JTextField slopeangle;
JTextField g;
JTextField objectmass;
public DataPanel()
{
this.setLayout(new BorderLayout());
this.setSize(250,800);
this.setBackground(Color.GRAY);
slopeangle = new JTextField(20);
g = new JTextField(20);
objectmass = new JTextField(20);
this.add(slopeangle);
this.add(g);
this.add(objectmass);
}
}
As has been mentioned, you will want to use layout managers to best arrange your components in your GUI. I would override the getPreferredSize() method of the graphics component but let everything else fall to its own innate preferred size. GridBagLayout could be used to easily arrange a grid of JTextFields, and BorderLayout is great for overall arrangements of the GUI. For instance:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
#SuppressWarnings("serial")
public class PrimaryPanel extends JPanel {
private ForcePanel forcePanel = new ForcePanel();
private DataPanel dataPanel = new DataPanel();
public PrimaryPanel() {
setLayout(new BorderLayout());
add(forcePanel, BorderLayout.CENTER);
add(dataPanel, BorderLayout.LINE_END);
}
private static void createAndShowGUI() {
PrimaryPanel paintEg = new PrimaryPanel();
JFrame frame = new JFrame("PrimaryPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(paintEg);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
#SuppressWarnings("serial")
class ForcePanel extends JPanel {
private static final int PREF_W = 750;
private static final int PREF_H = 800;
public ForcePanel() {
setBackground(Color.black);
}
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H); }
}
#SuppressWarnings("serial")
class DataPanel extends JPanel {
private static final int TEXT_FIELD_COLUMNS = 10;
private static final int GAP = 5;
private static final Insets RIGHT_GAP_INSETS = new Insets(GAP, GAP, GAP, 2 * GAP);
private static final Insets BALANCED_INSETS = new Insets(GAP, GAP, GAP, GAP);
public static final String[] FIELD_LABELS = {
"Slope Angle", "G", "Object Mass",
"Time Steps", "Max Time", "Fubarlicious!"
};
private Map<String, JTextField> labelFieldMap = new HashMap<>();
public DataPanel() {
JPanel labelFieldPanel = new JPanel(new GridBagLayout());
int row = 0;
for (String fieldLabelLText : FIELD_LABELS) {
JLabel fieldLabel = new JLabel(fieldLabelLText);
JTextField textField = new JTextField(TEXT_FIELD_COLUMNS);
labelFieldPanel.add(fieldLabel, getGbc(row, 0));
labelFieldPanel.add(textField, getGbc(row, 1));
labelFieldMap.put(fieldLabelLText, textField);
row++;
}
setLayout(new BorderLayout(GAP, GAP));
add(labelFieldPanel, BorderLayout.PAGE_START);
}
public static GridBagConstraints getGbc(int row, int column) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = column;
gbc.gridy = row;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
if (column == 0) {
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = RIGHT_GAP_INSETS;
} else {
gbc.anchor = GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = BALANCED_INSETS;
}
return gbc;
}
}
Which would look like: