Hello I am try to get jcomponent from other class.the components are displaying but my frame size changes.
Example.java
public class Example extends JFrame{
static JPanel panel = new JPanel();
static A a = new A();
static B b = new B();
static JComboBox<String> combo = new JComboBox<>();
static String value;
Example(){
setSize(400, 400);
combo.setBounds(450, 140, 50, 20);
combo.addItem("");
combo.addItem("a");
combo.addItem("b");
combo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
value = (String) combo.getSelectedItem().toString();
if(value.equals("a")){
panel.add(a.getLabel());
panel.remove(b.getLabel());
add(panel);
pack();
}else if(value.equals("b")){
panel.add(b.getLabel());
panel.remove(a.getLabel());
add(panel);
pack();
}
}
});
panel.add(combo);
this.add(panel);
setVisible(true);
}
}
A.java
public class A extends JFrame{
JPanel panel = new JPanel();
JLabel lab = new JLabel("Text");
A(){
lab.setBounds(280, 25, 150, 50);
lab.setVisible(true);
panel.add(lab);
add(panel);
}
public JLabel getLabel(){
return lab;
}
}
B.java
public class B extends JFrame{
JPanel panel = new JPanel();
JButton lab = new JButton("Hello");
B(){
lab.setBounds(380, 25, 250, 50);
lab.setVisible(true);
panel.add(lab);
add(panel);
}
public JButton getLabel(){
return lab;
}
}
Main.java
public class Main {
public static void main(String [] agrs) {
Example ex = new Example();
ex.setVisible(true);
}
}
when I run frame open as defined size but when I select a from combo box the frame size decreases any suggestion so as screen size remain same.
The quick and dirty way to solve this is to get rid of pack()
and subsitute revalidate()
and repaint
:
add(panel);
revalidate();
repaint();
// pack();
revalidate
tells the layout managers to re-lay out their components.
repaint
requests that the component be repainted, especially "dirty" regions
pack
tells the window to re-lay out all components and resize to the optimal size.
Much better would be to use a CardLayout, and the window and component size will remain constant, big enough to fit the largest component. ... and avoid all use of null layouts.
For example:
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Example2 extends JPanel {
public static final String[] COMBO_TEXTS = {"", "a", "b"};
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private DefaultComboBoxModel<String > comboModel = new DefaultComboBoxModel<>(COMBO_TEXTS);
private CardLayout cardLayout = new CardLayout();
public Example2() {
setLayout(cardLayout);
ComboListener comboListener = new ComboListener();
JComboBox<String> combo = new JComboBox<>(comboModel);
combo.addActionListener(comboListener);;
JPanel panelBlank = new JPanel();
panelBlank.add(combo);
JPanel panelWithText = new JPanel();
combo = new JComboBox<>(comboModel);
combo.addActionListener(comboListener);;
panelWithText = new JPanel();
panelWithText.add(combo);
panelWithText.add(new JLabel("Text"));
JPanel panelWithButton = new JPanel();
combo = new JComboBox<>(comboModel);
combo.addActionListener(comboListener);;
panelWithButton = new JPanel();
panelWithButton.add(combo);
panelWithButton.add(new JButton("Hello"));
add(panelBlank, COMBO_TEXTS[0]);
add(panelWithText, COMBO_TEXTS[1]);
add(panelWithButton, COMBO_TEXTS[2]);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private class ComboListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JComboBox<String> combo = (JComboBox<String>)e.getSource();
String item = combo.getSelectedItem().toString();
cardLayout.show(Example2.this, item);
}
}
private static void createAndShowGui() {
Example2 mainPanel = new Example2();
JFrame frame = new JFrame("Example2");
frame.setDefaultCloseOperation(JFrame.EXIT_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();
}
});
}
}
This simplifies things and makes it harder to shoot yourself in the foot. So rather than this:
public void actionPerformed(ActionEvent e) {
value = (String) combo.getSelectedItem().toString();
if(value.equals("a")){
panel.add(a.getLabel());
panel.remove(b.getLabel());
// add(panel);
// pack();
}else if(value.equals("b")){
panel.add(b.getLabel());
panel.remove(a.getLabel());
// add(panel);
// pack();
}
add(panel);
revalidate();
repaint();
}
Your ActionListener's actionPerformed method is just this:
public void actionPerformed(ActionEvent e) {
JComboBox<String> combo = (JComboBox<String>)e.getSource();
String item = combo.getSelectedItem().toString();
cardLayout.show(Example2.this, item);
}
For more on the CardLayout, its uses and functionality, please check out the CardLayout Tutorial. But in a nutshell, it automates the process of swapping "views" in a GUI, making it much harder to shoot yourself in the foot.
Try to use revalidate()
instead of pack()
; pack()
automatically resizes your frame in order to fit the subcomponents:
javadoc for pack():
Causes this Window to be sized to fit the preferred size and layouts
of its subcomponents. The resulting width and height of the window are
automatically enlarged if either of dimensions is less than the
minimum size as specified by the previous call to the setMinimumSize
method.