Java Swing Checkboxes in a SplitPane - java

The current layout I am after is simply a split pane horizonal where on the left side are checkboxes and the right side will be output. I will eventually add a submit button the left side after the user checks all wanted items and I will display the result on the right side. The current issue is that I can't even get the background color to show up and the checkboxes are adding wonky. At certain times I can only see one checkbox in the left panel and I am not sure why, and I also set every container to visible and still not able to see it. I add them in the addBoxes function.
import java.awt.Color;
import java.util.ArrayList;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
public class CheckBox2 extends JFrame {
private ArrayList<JCheckBox> boxes = new ArrayList<JCheckBox>();
JLabel leftLabel;
JLabel rightLabel;
JSplitPane splitPane;
public CheckBox2() {
leftLabel = new JLabel();
rightLabel = new JLabel();
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(leftLabel), new JScrollPane(rightLabel) );
leftLabel.setBackground(Color.BLUE);
rightLabel.setBackground(Color.RED);
leftLabel.setVisible(true);
rightLabel.setVisible(true);
splitPane.setVisible(true);
add(splitPane);
}
void addBoxes() {
int i = 0;
for ( i = 0; i < 1; i++ ) {
add(new JCheckBox("word" + i ) );
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
CheckBox2 cb = new CheckBox2();
cb.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
cb.setSize(340, 340);
cb.setVisible(true);
cb.addBoxes();
}
}

Start by having a read of Laying Out Components Within a Container and How to Use Split Panes both which contain plenty of examples.
Swing layouts are lazy. This means that unless you purposefully trigger a layout pass, any changes won't be reflected on the UI (until a layout pass is triggered, such as resizing the window or making it visible for the first time).
While you can call revalidate and repaint on the container your are changing, in your case, simply calling setVisible last will have the same desired effect
Thanks, so with that I'm just getting the last checkbox, checkbox 9 to show up but it's not giving split screen or showing color :(
That's because JFrame, by default, uses a BorderLayout, which only allows a single component to be managed at any of the five available positions. Instead, you need to add you checkboxes to one of the containers in the split pane.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
public class CheckBox2 extends JFrame {
private ArrayList<JCheckBox> boxes = new ArrayList<JCheckBox>();
JSplitPane splitPane;
private JPanel leftPanel;
private JPanel rightPanel;
public CheckBox2() {
leftPanel = new JPanel(new GridBagLayout());
rightPanel = new JPanel(new GridBagLayout()) {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
};
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, new JScrollPane(rightPanel));
leftPanel.setBackground(Color.BLUE);
rightPanel.setBackground(Color.RED);
add(splitPane);
addBoxes();
}
void addBoxes() {
int i = 0;
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (i = 0; i < 10; i++) {
leftPanel.add(new JCheckBox("word" + i), gbc);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
CheckBox2 cb = new CheckBox2();
cb.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
cb.pack();
cb.setLocationRelativeTo(null);
cb.setVisible(true);
}
}

Related

Radio button event handlers

I'm having some trouble with a java project. I've made an empty GUI interface, and now I need to add some functionality to it. I'm stuck, however, on how to go about that. The basic layout has 4 radio buttons, Rectangle, Box, Circle, and Cylinder. I have a group panel that has 4 separate panels that each have text boxes with labels for entering height, length, width, and radius. Here's how it looks: GUI layout. Depending on the radio button that is selected, certain boxes that aren't needed should be hidden. For example, if Rectangle is selected, only the boxes for length and width should be visible.
The main frame that will display everything is here:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JButton;
import java.awt.Font;
public class GUIFrame extends JFrame
{
//private final BorderLayout layout;
private final FlowLayout layout;
private final JLabel lblTitle;
private final JButton btnProc;
public GUIFrame()
{
super("GUI Layout");
Font titleFont = new Font("Verdana", Font.BOLD, 26);
btnProc = new JButton("Click to Process");
lblTitle = new JLabel("Figure Center");
lblTitle.setFont(titleFont);
widthPanel myWidth = new widthPanel();
myWidth.setLocation(0, 400);
lengthPanel myLength = new lengthPanel();
heightPanel myHeight = new heightPanel();
radiusPanel myRadius = new radiusPanel();
radioButtonPanel myButtons = new radioButtonPanel();
//layout = new BorderLayout(3, 2);
layout = new FlowLayout();
JPanel txtGroup = new JPanel();
txtGroup.setLayout(new GridLayout(2, 2));
txtGroup.add(myWidth);
txtGroup.add(myLength);
txtGroup.add(myRadius);
txtGroup.add(myHeight);
setLayout(layout);
add(lblTitle);
add(myButtons);
add(txtGroup);
add(btnProc);
if(myButtons.btnRectangle.isSelected())
{
myHeight.setVisible(false);
myRadius.setVisible(false);
}
}
private class RadioButtonHandler implements ItemListener
{
#Override
public void itemStateChanged(ItemEvent event)
{
}
}
}
I can get this working using if statements, but I'm supposed to be using event handlers and I'm lost on how to code that to get it to work properly.
if it helps, here's the code for the button panel:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import java.awt.GridLayout;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
public class radioButtonPanel extends JPanel
{
private final JRadioButton btnRectangle;
private final JRadioButton btnBox;
private final JRadioButton btnCircle;
private final JRadioButton btnCylinder;
private final ButtonGroup radioButtonGroup;
private final JLabel label;
private final JPanel radioPanel;
public radioButtonPanel()
{
radioPanel = new JPanel();
radioPanel.setLayout(new GridLayout(5,1));
btnRectangle = new JRadioButton("Rectangle", true);
btnBox = new JRadioButton("Box", false);
btnCircle = new JRadioButton("Circle", false);
btnCylinder = new JRadioButton("Cylinder", false);
label = new JLabel("Select A Figure:");
radioPanel.add(label);
radioPanel.add(btnRectangle);
radioPanel.add(btnBox);
radioPanel.add(btnCircle);
radioPanel.add(btnCylinder);
radioButtonGroup = new ButtonGroup();
radioButtonGroup.add(btnRectangle);
radioButtonGroup.add(btnBox);
radioButtonGroup.add(btnCircle);
radioButtonGroup.add(btnCylinder);
add(radioPanel);
}
}
And a sample of one of the panels. They all follow the same setup, just different variable names.
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPanel;
import java.awt.GridLayout;
public class heightPanel extends JPanel
{
private final JLabel lblHeight;
private final JTextField txtHeight;
private final JPanel myHeight;
public heightPanel()
{
myHeight = new JPanel();
myHeight.setLayout(new GridLayout(2,1));
lblHeight = new JLabel("Enter Height:");
txtHeight = new JTextField(10);
myHeight.add(lblHeight);
myHeight.add(txtHeight);
add(myHeight);
}
}
The below code should give you a quick introduction of how to use event listener/handler for your button group (JRadioButtons).
but I'm supposed to be using event handlers and I'm lost on how to
code that to get it to work properly.
//add listener to the rectangle button and should be the same for the other `JRadioButtons` but with different `identifiers`.
btnRectangle.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnRectangle){
//TODO
}
}
});
Depending on the radio button that is selected, certain boxes that
aren't needed should be hidden. For example, if Rectangle is selected,
only the boxes for length and width should be visible.
//To hide JTextFields use
void setVisible(boolean visible) method. You should pass false as the argument to the method if you want to hide the JTextField.
Example:
btnRectangle.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnRectangle){
TextFieldName.setVisible(false); // set the textfields that you want to be hidden once the Rectangle button is chosen.
}
}
});

How to disable Divider in JsplitPane from hiding one component?

I have a jsplitPane and 2 component. I want to not let the user click the divider to maximize the top component.
Here is my code.
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JSplitPane;
public class MovingJSplitPaneDivider {
public static void main(String[] a) {
JFrame horizontalFrame = new JFrame();
horizontalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent topButton = new JButton("Left");
JComponent bottomButton = new JButton("Right");
final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setTopComponent(topButton);
splitPane.setBottomComponent(bottomButton);
horizontalFrame.add(splitPane, BorderLayout.CENTER);
horizontalFrame.setSize(150, 150);
horizontalFrame.setVisible(true);
splitPane.setDividerLocation(0.5);
}
}
What I want exactly is that to block the user when he wants to move down the divider.

How to set number of selectable JRadioButton

How would I go about setting the number of selectable items of JRadioButtons?
I tried adding the radiobuttons to a buttongroup, and overriding the buttongroup class, but cant figure which method to modify.
Basically, I want to allow selection of only two radiobuttons. I am aware this is possible using checkboxes, but I need the "roudness" of the radiobuttons, and figure this should be an easier way to go, instead of modifying the look and feel of the checkbox.
Thanks a bunch! :)
Here is an example:
package com.haraj.test.java;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
public class JRadioButtonTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = (JPanel) frame.getContentPane();
contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new GridLayout());
final Queue<JRadioButton> selectedButtons = new LinkedList<JRadioButton>();
ItemListener listener = new ItemListener()
{
#Override
public void itemStateChanged(ItemEvent e)
{
JRadioButton newButton = (JRadioButton) e.getSource();
if(e.getStateChange() == ItemEvent.DESELECTED) selectedButtons.remove(newButton);
else
{
if(selectedButtons.size() == 2)
{
JRadioButton oldButton = selectedButtons.poll();
if(oldButton != newButton) oldButton.setSelected(false);
}
selectedButtons.add(newButton);
}
}
};
JRadioButton[] buttons = new JRadioButton[6];
for(int i = 0; i < buttons.length; i++)
{
buttons[i] = new JRadioButton();
buttons[i].addItemListener(listener);
contentPane.add(buttons[i]);
}
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
}
One way would be to add an ActionListener to each individual radiobutton which updates a counter if the button is selected.
You can read about jRadioButton functions HERE.
You can then do a function if the counter hits two which makes the other buttons grey (unclickable) using:
.setActionCommand("disable");
You can find more info about the possible methods in the API.

How do I make my chat program scroll down as the chat moves along?

I'm making a simple chat GUI. I've come into a problem where my program isn't scrolling down as the chat moves along. I'm also unsure about how to add a scroll bar/pane to the program, without messing everything up by putting my main text area into a panel and destroying the look of the interface. How do I adjust the main chat box, without screwing it up and making it look ugly by putting the chatBox in a JPanel. I'll post all of my code below.
MainGUI class:
package coltGUI;
import java.awt.BorderLayout;
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;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
public class MainGUI implements ActionListener {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
MainGUI gui = new MainGUI();
gui.display();
}
JButton sendMessage;
JTextField messageBox;
JTextArea chatBox;
public void display() {
JFrame frame = new JFrame("Colt Chat");
JPanel southPanel = new JPanel();
frame.getContentPane().add(BorderLayout.SOUTH, southPanel);
southPanel.setBackground(Color.BLUE);
southPanel.setLayout(new GridBagLayout());
messageBox = new JTextField(30);
sendMessage = new JButton("Send Message");
chatBox = new JTextArea();
chatBox.setEditable(false);
frame.getContentPane().add(BorderLayout.CENTER, chatBox);
chatBox.setLineWrap(true);
GridBagConstraints left = new GridBagConstraints();
left.anchor = GridBagConstraints.WEST;
GridBagConstraints right = new GridBagConstraints();
right.anchor = GridBagConstraints.EAST;
right.weightx = 2.0;
southPanel.add(messageBox, left);
southPanel.add(sendMessage, right);
sendMessage.addActionListener(this);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(470, 300);
}
public void actionPerformed(ActionEvent event) {
if (messageBox.getText().length() < 1) {
// do nothing
} else {
chatBox.append(messageBox.getText() + "\n");
messageBox.setText("");
}
}
}
Just add the text area to a JScrollPane and then add the scrollpane to the frame. There is no need for a panel.
//frame.getContentPane().add(BorderLayout.CENTER, chatBox);
frame.add(new JScrollPane(chatBox), BorderLayout.CENTER);
Note that constraints should be specified as the second parameter of the add(...) method, not the first.
Also, since JDK5, you don't need to use getContentPane(), the frame.add(..) method will do this for you.
If you want automatic scrolling you can check out Text Area Scrolling.
First you need to wrap chatBox in a JScrollPane like this:
frame.add(new JScrollPane(chatBox), BorderLayout.CENTER);
Second after appending the message to chatBox you need to force it to scroll to the end which can be done with the following:
chatBox.setCaretPosition(chatBox.getDocument().getLength());

Hide left/right component of a JSplitPane (or different layout)

At the moment I write a little client application. I have a window with a JTextArea (Display area for the server output) and a user-list.
My plan is to show/hide this user-list over a menu item, but I don't know how. My ideas:
Use a BorderLayout: Without a JScrollPane for the list. It works, but I cannot change the width of the user-list (Because BorderLayout.WEST and BorderLayout.EAST ignore the width)
Use a BorderLayout with a JScrollPane for the user list and show/hide the JScrollPane -> Does not work, don't ask me why...anyway, this way is not a nice solution
Use a JSplitPane, set the resize weight to 0.9. When the user-list should disappear, I minimize the right component (aka the user list) -> How ?
My code at the moment:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
public class SplitPaneTest extends JFrame implements ActionListener
{
private JSplitPane splitPane;
private JTextArea textDisplay;
private JList<String> listUser;
private JScrollPane scrollTextDisplay;
private JScrollPane scrollListUser;
private JCheckBox itemShowUser;
public static void main(String[] args)
{
new SplitPaneTest();
}
public SplitPaneTest()
{
setTitle("Chat Client");
setMinimumSize(new Dimension(800, 500));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textDisplay = new JTextArea();
listUser = new JList<>();
DefaultListModel<String> modelUser = new DefaultListModel<>();
listUser.setModel(modelUser);
modelUser.addElement(new String("User 1"));
modelUser.addElement(new String("User 2"));
modelUser.addElement(new String("User 3"));
scrollTextDisplay = new JScrollPane(textDisplay);
scrollListUser = new JScrollPane(listUser);
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setLeftComponent(scrollTextDisplay);
splitPane.setRightComponent(scrollListUser);
splitPane.setResizeWeight(0.9);
setContentPane(splitPane);
JMenuBar menubar = new JMenuBar();
JMenu menuWindow = new JMenu("Window");
itemShowUser = new JCheckBox("Show user list");
itemShowUser.addActionListener(this);
itemShowUser.setSelected(true);
menuWindow.add(itemShowUser);
menubar.add(menuWindow);
setJMenuBar(menubar);
setVisible(true);
}
public boolean isUserListEnabled()
{
return itemShowUser.isSelected();
}
public void setUserListEnabled(boolean status)
{
scrollListUser.setVisible(status);
}
#Override
public void actionPerformed(ActionEvent ae)
{
if(ae.getSource() == itemShowUser)
{
boolean status = isUserListEnabled();
setUserListEnabled(status);
}
}
}
And the result is:
And with hidden JScrollPane scrollListUser:
Can anybody give me a tipp ? The user-list is still visible ( I thought the JSplitPane would repaint..) .I come from Qt (C++) and in Qt I could use a dock widget - but Swing does not have one and to use third libs....I don't know - maybe there is a solution.
Looks like the splitPane can't handle invisible components well - a way out is to add/remove the scrollPane as appropriate:
public void setUserListEnabled(boolean status)
{
splitPane.setRightComponent(status ? scrollListUser : null);
splitPane.revalidate();
}

Categories

Resources