I have a problem with Swing interface on java. Explaination: I have a Combobox with 1, 2, 3, 4, 5 items. When an exact item is selected I need to create some more comboboxes the number of which depends on the selected item. So, if number 5 is selected, 5 more comboboxes must appear in the frame. I used ActionListener but it did not work properly. However, the same code but outside Actionlistener works well. What a problem can it be?
public class FrameClass extends JFrame {
JPanel panel;
JComboBox box;
String[] s = {"1", "2", "3", "4", "5"};
String[] s1 = {"0", "1", "2", "3", "4", "5"};
public FrameClass() {
panel = new JPanel();
box = new JComboBox(s);
JComboBox adults = new JComboBox(s);
JComboBox children = new JComboBox(s1);
panel.add(box, BorderLayout.CENTER);
box.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for(int i = 0; i <= box.getSelectedIndex(); i++) {
panel.add(adults, BorderLayout.WEST);
panel.add(children, BorderLayout.WEST);
}
}
});
add(panel);
}
}
public class MainClass {
public static void main(String[] args) {
JFrame frame = new FrameClass();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.getContentPane().setBackground(Color.WHITE);
frame.setVisible(true);
}
}
The problem that you don't inform the layout manager about new elements in your panel.
Here is the correct variant of your action listener:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class FrameClass extends JFrame {
JPanel panel;
JComboBox<String> box;
String[] s = {"1", "2", "3", "4", "5"};
String[] s1 = {"0", "1", "2", "3", "4", "5"};
public FrameClass() {
panel = new JPanel();
box = new JComboBox(s);
JComboBox[] adults = new JComboBox[5];
JComboBox[] children = new JComboBox[5];
for (int i = 0; i < 5; i++) {
adults[i] = new JComboBox<>(s);
children[i] = new JComboBox<>(s1);
}
panel.add(box, BorderLayout.CENTER);
JPanel nested = new JPanel();
add(nested, BorderLayout.EAST);
box.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
nested.removeAll();
nested.setLayout(new GridLayout(box.getSelectedIndex() + 1, 2));
for (int i = 0; i <= box.getSelectedIndex(); i++) {
nested.add(adults[i]);
nested.add(children[i]);
}
getContentPane().revalidate();
getContentPane().repaint();
pack();
}
});
add(panel);
}
public static void main(String[] args) {
JFrame frame = new FrameClass();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.getContentPane().setBackground(Color.WHITE);
frame.setLocationRelativeTo(null); // center the window
frame.setVisible(true);
}
}
Related
How do i create a jframe that organizes the text box and jbuttons, with the textbox on top and a 3 by 4 grid layout of buttons 1-10?
"TEXT BOX HERE"
[1][2][3]
[4][5][6]
[7][8][9]
[(][0][)]
This is what I have so far:
setTitle("Test");
setSize(400, 400);
// Create JButton and JPanel
JButton[] buttons = new JButton[12];
JButton buttonLpar = new JButton("(");
JButton buttonRpar = new JButton(")");
JPanel panel = new JPanel();
JPanel panel2 = new JPanel(new GridLayout(3, 4));
// adding 10 buttons
for(int i = 0; i < 10; i++) {
buttons[i] = new JButton(String.valueOf(i));
}
buttons[11].add(buttonLpar);
buttons[12].add(buttonRpar);
JTextField text = new JTextField("",10);
text.setFont(new Font("Helvetica Neue", Font.BOLD, 12));
panel.add(text, BorderLayout.NORTH);
panel.add(panel2, BorderLayout.CENTER);
this.getContentPane().add(panel);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
But that's where I'm stuck.
Okay I should note that I need a for loop to populate 3 by 4 gridlayout. But I don't know what I need in the loop.
For this kind of grid, assuming you create it on the go, you just need to have an if-else to see if you're on the last row of data.
For example:
import java.awt.GridLayout;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GridLayoutWithEmptyComponents {
private JFrame frame;
private JPanel pane;
private JPanel buttonsPane;
private JButton[] buttons;
private void createAndShowGUI() {
frame = new JFrame(getClass().getSimpleName());
pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
buttonsPane = new JPanel();
buttonsPane.setLayout(new GridLayout(4, 3));
buttons = new JButton[10];
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton("" + (i + 1));
if (i == buttons.length - 1) {
buttonsPane.add(new JButton("("));
buttonsPane.add(buttons[i]);
buttonsPane.add(new JButton(")"));
} else {
buttonsPane.add(buttons[i]);
}
}
pane.add(new JLabel("Text box"));
pane.add(buttonsPane);
frame.add(pane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new GridLayoutWithEmptyComponents()::createAndShowGUI);
}
}
Or you could have all the data in a String[] like:
String[] buttonValues = {"1", "2", "3", ..., "8", "9", "(", "0", ")"};
And then use those values as the JButtons values without the need for an if-else inside the loop.
I have a Java GUI project where I am creating an ATM. I have everything setup, but for some reason my number pad on the left is not displaying properly. It should appear as a 4x3 grid of numbers, but it is just displaying a 9. I have checked to make sure it is in a GridLayout and I have checked my loop, but I possibly may have looked over something. Any help is appreciated, thanks!
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.*;
public class ATMProject extends JPanel implements ActionListener {
private JPanel mainPanel = null;
private JPanel btnPanel = null;
private JPanel userBtns = null;
private JTextArea textArea = null;
private JPanel keyPanel = null;
private JTextField numField = null;
private JPanel numpadPanel = null;
private JButton[] userButtons = null;
private JButton[] keypadButtons = null;
private String[] btnPanelbtns = { "A", "B", "C" };
private String[] numpadPanelbtns = { "7", "4", "1", "8", "5", "2", "9", "6", "3", "0", ".", "CE" };
public ATMProject() {
super();
mainPanel = new JPanel();
this.setLayout(new BorderLayout());
this.add(mainPanel);
btnPanel = new JPanel();
btnPanel.setLayout(new GridLayout(3, 1));
this.add(btnPanel, BorderLayout.EAST);
textArea = new JTextArea();
this.add(textArea, BorderLayout.CENTER);
keyPanel = new JPanel();
keyPanel.setLayout(new BorderLayout());
this.add(keyPanel, BorderLayout.WEST);
numpadPanel = new JPanel();
numpadPanel.setLayout(new GridLayout(0, 3));
keyPanel.add(numpadPanel, BorderLayout.CENTER);
numField = new JTextField();
keyPanel.add(numField, BorderLayout.NORTH);
userButtons = new JButton[btnPanelbtns.length];
for (int i = 0; i < userButtons.length; i++) {
userButtons[i] = new JButton(btnPanelbtns[i]);
userButtons[i].addActionListener(this);
btnPanel.add(userButtons[i]);
}
keypadButtons = new JButton[numpadPanelbtns.length];
for (int i = 0; i < userButtons.length; i++) {
keypadButtons[i] = new JButton(numpadPanelbtns[i]);
keypadButtons[i].addActionListener(this);
numpadPanel.add(keypadButtons[i]);
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
MyFrame mf = new MyFrame();
}
}
import javax.swing.JFrame;
public class MyFrame extends JFrame {
private ATMProject atm = null;
public MyFrame(){
super();
atm = new ATMProject();
this.add(atm);
this.setTitle("ATM");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setSize(800,300);
this.setVisible(true);
}
}
This is how it is supposed to appear:
You're adding you buttons to keyPanel...
keyPanel.add(keypadButtons[i]);
which is using a BorderLayout...
keyPanel = new JPanel();
keyPanel.setLayout(new BorderLayout());
so only the last component added to it will be laid out by the panel.
One imagines you should be adding them to numpadPanel instead...
numpadPanel.add(keypadButtons[i]);
Yeah, I have that numpadPanel.add(keypadButtons[i]); and I am getting just 7 8 9 vertically.
That's kind of how GridLayout works, you could force into a horizontal priority mode by using something more like
numpadPanel.setLayout(new GridLayout(0, 3));
My loop was incorrectly written. for (int i = 0; i < userButtons.length; i++) my program was only outputting 3 buttons because userButtons.length only had 3 elements. I changed userButtons.length to numpadPanelbtns.length and it fixed it because there are 12 elements in the numpadPanelbtns array.
I created two class that extends JPanel and want to add that two class in one Frame. But i am unable to do it. Anyone help please.
my classes are -->
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CalButton extends JPanel {
private JButton[] buttons;
private static final String[] buttonNames = { "7", "8", "9", "/", "4", "5",
"6", "*", "1", "2", "3", "-", "0", ".", "=", "+" };
private JPanel buttonPanel;
public CalButton() {
// TODO Auto-generated constructor stub
buttons = new JButton[buttonNames.length];
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(4, 4, 3, 3));
for(int i=0; i<buttonNames.length; i++){
buttons[i] = new JButton(buttonNames[i]);
buttonPanel.add(buttons[i]);
}
}
}
Another Class-->
import java.awt.GridLayout;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class CalField extends JPanel {
private JPanel panelField;
private JTextField field;
public CalField() {
// TODO Auto-generated constructor stub
panelField = new JPanel();
panelField.setLayout(new GridLayout(1, 1,5,5));
field = new JTextField(20);
panelField.add(field);
}
}
Main class-->
public class Calculator {
public static void main(String[] args) {
JFrame application = new JFrame("Calculator");
CalField calField = new CalField();
CalButton calButton = new CalButton();
application.setLayout(new GridLayout(2, 1));
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.setSize(400, 450);
application.setVisible(true);
}
}
Anyone kindly solve this problem please. i'm stuck with this problem.
public CalButton() {
// TODO Auto-generated constructor stub
buttons = new JButton[buttonNames.length];
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(4, 4, 3, 3));
for(int i=0; i<buttonNames.length; i++){
buttons[i] = new JButton(buttonNames[i]);
buttonPanel.add(buttons[i]);
}
}
The CalButton class already "is a" JPanel because you extend JPanel so there is no need to create another JPanel. Just add your buttons to the class:
public CalButton() {
// TODO Auto-generated constructor stub
buttons = new JButton[buttonNames.length];
//buttonPanel = new JPanel();
//buttonPanel.setLayout(new GridLayout(4, 4, 3, 3));
setLayout(new GridLayout(4, 4, 3, 3));
for(int i=0; i<buttonNames.length; i++){
buttons[i] = new JButton(buttonNames[i]);
//buttonPanel.add(buttons[i]);
add(buttons[i]);
}
}
Same with your CalcField class except in this case you probably don't need to set the layout manager. You can probably use the default FlowLayout.
Then the second problem is that you never add these panels to the frame:
CalField calField = new CalField();
CalButton calButton = new CalButton();
//application.setLayout(new GridLayout(2, 1));
application.add(calField, BorderLayout.PAGE_START);
application.add(calButton, BorderLayout.CENTER);
I want to add a scrollpane in the frame window or comboPanel.
Below code, the guiFrame.add(scrollpane) is not working, why it is not working?
How can I add the scrollpane to comboPanel or the guiFrame?
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ExtraComboBox {
private int maxFields = 4; // The max number of fields allowed in the dialog
JComboBox fruits[] = new JComboBox[maxFields];
JPanel comboPanel;
JFrame guiFrame;
String[] valOptions3 = { "&" };
String[] valOptions2 = { "|->", "|=>" };
String[] valOptions1 = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
String[] valOptions0 = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
String[] fruitOptions1 = { "", "Delay1", "Delay2", "Delay3" };
JButton addField;
int count1 = 0;
JLabel dudel[] = new JLabel[maxFields];
JComboBox dude2[] = new JComboBox[maxFields];
String[] valOptions = { "Unknown", "0", "1" };
String[] s = { "a", "b", "c", "d", "e", "f", "g", "h", "i" };
private JLabel comboLbl;
public static void main(String[] args) {
new ExtraComboBox();
}
public ExtraComboBox() {
guiFrame = new JFrame();
// make sure the program exits when the frame closes
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("ComboBox GUI");
guiFrame.setSize(350, 350);
// The first JPanel contains a JLabel and JCombobox
comboPanel = new JPanel();
addField = new JButton("Add Field");
addField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource().equals(addField)) {
if (count1 < maxFields) {
comboLbl = new JLabel("Select a relation:");
fruits[count1] = new JComboBox<String>(fruitOptions1);
MyItemListener2 actionListener2 = new MyItemListener2(count1);
fruits[count1].addItemListener(actionListener2);
// System.out.println("HI: " + fruits[count1].getParent());
dude2[count1] = new JComboBox<String>();
System.out.println("ADD FIELDS: " + count1);
comboPanel.add(comboLbl);
comboPanel.add(fruits[count1]);
comboPanel.add(dude2[count1]);
guiFrame.validate();
guiFrame.repaint();
count1++;
} else {
System.out.println("You reached the maximum of 4 fields.");
}
}
}
});
comboPanel.setLayout(new BoxLayout(comboPanel, BoxLayout.Y_AXIS));
comboPanel.add(addField);
// The JFrame uses the BorderLayout layout manager.
// Put the two JPanels and JButton in different areas.
guiFrame.add(comboPanel, BorderLayout.NORTH);
// make sure the JFrame is visible
guiFrame.setVisible(true);
}
class MyItemListener2 implements ItemListener {
private int index;
public MyItemListener2(int pIndex) {
super();
index = pIndex;
}
// This method is called only if a new item has been selected.
public void itemStateChanged(ItemEvent evt) {
if (evt.getStateChange() == ItemEvent.SELECTED) {
// Item was just selected
System.out.println("COUNTER: " + index);
System.out.println(evt.getItem());
dude2[index].removeAllItems();
switch ((String) evt.getItem()) {
case "Delay1":
for (int i = 0; i < valOptions1.length; i++) {
dude2[index].addItem(valOptions1[i]); // dude1 = new JComboBox(valOptions1);
System.out.println(valOptions1[i]);
}
break;
case "Delay2":
for (int j = 0; j < valOptions2.length; j++) {
System.out.println(valOptions2[j]);
dude2[index].addItem(valOptions2[j]); // dude1 = new JComboBox(valOptions1);
}
break;
case "Delay3":
for (int j = 0; j < valOptions3.length; j++) {
System.out.println(valOptions3[j]);
dude2[index].addItem(valOptions3[j]); // dude1 = new JComboBox(valOptions1);
}
}
}
}
}
}
How can I add the scrollpane to comboPanel or the guiFrame?
You add the comboPanel to the JViewport of the JScrollPane and then you add the scroll pane to the JFrame.
//guiFrame.add(comboPanel, BorderLayout.NORTH);
JScrollPane scrollPane = new JScrollPane( comboPanel );
guiFrame.add(scrollPane, BorderLayout.CENTER);
It is better to add the scrollpane to the CENTER, then it will get all the space available to the frame.
This question already has answers here:
How can I change the width of a JComboBox dropdown list?
(7 answers)
Closed 8 years ago.
How can I set a fixed width of a JComboboxs popup-menu that is using GridBagLayout and fill=HORIZONTAL?
One of the things I tried is to just override the getSize() method but dose not work.
public class ComboBoxSize extends JFrame {
public static void main(String args[]) {
// THE COMBOBOX
String labels[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
JComboBox<String> comboBox = new JComboBox<String>(labels) {
public Dimension getSize() {
Dimension d = getPreferredSize();
d.width = 50;
return d;
}
};
comboBox.setMaximumRowCount(comboBox.getModel().getSize());
// ADD COMBOBOX TO PANEL
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(comboBox, c);
// ADD PANEL TO FRAME
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Here is the solution, this worked for me, add this PopupMenuListener to your JComboBox:
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.ComboPopup;
public class CustomComboBoxPopupMenuListener implements PopupMenuListener {
// ==============================================================================
// Members
// ==============================================================================
private int bgTop = 0;
private int bgLeft = 0;
private int bgRight = 0;
private int bgBottom = 0;
// ==============================================================================
// Constructors
// ==============================================================================
public CustomComboBoxPopupMenuListener() {
super();
}
// ==============================================================================
// Methods
// ==============================================================================
public void popupMenuCanceled(PopupMenuEvent e) {
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
final JComboBox box = (JComboBox) e.getSource();
final Object comp = box.getUI().getAccessibleChild(box, 0);
if (!(comp instanceof JPopupMenu)) {
return;
}
final JPopupMenu popupMenu = (JPopupMenu) comp;
popupMenu.setBorder(null);
if (popupMenu.getComponent(0) instanceof JScrollPane) {
final JScrollPane scrollPane = (JScrollPane) popupMenu
.getComponent(0);
scrollPane.setBorder(BorderFactory.createEmptyBorder(bgTop, bgLeft,
bgBottom, bgRight));
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
if (popupMenu instanceof ComboPopup) {
final ComboPopup popup = (ComboPopup) popupMenu;
final JList list = popup.getList();
list.setBorder(null);
final Dimension size = list.getPreferredSize();
size.width = Math.max(box.getPreferredSize().width + bgLeft
+ bgRight, box.getWidth());
size.height = Math.min(scrollPane.getPreferredSize().height
+ bgTop + bgBottom, size.height + bgTop + bgBottom);
scrollPane.setPreferredSize(size);
scrollPane.setMaximumSize(size);
}
}
}
}
Example in your code:
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ComboBoxSize extends JFrame {
public static void main(String args[]) {
// THE COMBOBOX
String labels[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
JComboBox<String> comboBox = new JComboBox<String>(labels);
comboBox.setMaximumRowCount(comboBox.getModel().getSize());
comboBox.addPopupMenuListener(new CustomComboBoxPopupMenuListener());
// ADD COMBOBOX TO PANEL
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(comboBox, c);
// ADD PANEL TO FRAME
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Source: click here