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

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();
}

Related

JMenuItem reuse

Here is the minimal working application :
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class JMenuItemReuse {
public static void main(String[] args) {
SwingUtilities.invokeLater(TestFrame::new);
}
}
class TestFrame extends JFrame {
public TestFrame() {
super();
JPanel panel = new JPanel();
JPopupMenu menu1 = new JPopupMenu();
JPopupMenu menu2 = new JPopupMenu();
JMenuItem item1 = new JMenuItem("reused");
JMenuItem item2 = new JMenuItem("not reused");
menu1.add(item1);
menu2.add(item1); // works if this line is commented
menu2.add(item2);
panel.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if (SwingUtilities.isRightMouseButton(e)) {
menu1.show(panel, e.getX(), e.getY());
} else {
menu2.show(panel, e.getX(), e.getY());
}
}
});
panel.add(new JLabel("popup-test"));
add(panel);
setPreferredSize(new Dimension(400, 400));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
The problem is that the popup menus do not work as expected when at least one menu item is reused. It is not a big issue, can be easily avoided by duplicating the reused menu item, but I am still wondering why does it happen. Any ideas?
A JMenuItem belongs to one, and only one, JPopupMenu (or any other menu). You cannot add a Swing component to more than one container; if you do, then the component will automatically be removed from the previous container.
Actaully if you want, you can create Actions. Actions can be shared and added to multiple components (JMenuItems, JButtons etc). You can even enable/disable the Action which will enable/disable all the components at the same time.

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.
}
}
});

JScrollPane - content and Scrollbar not rendering

I'm creating a small Game of Life application. I'm using a 'dynamic universe' for all my cells (named Tiles in my project). But for some reason my JScrollPane and JButtons aren't rendering into the frame. I just get a empty JFrame. The controller is returning values and the buttons are getting constructed and added to the panel. It's just that jsp.setViewportView(p); doesn't seem to update the UI.
Main:
GOLController controller = new GOLController();
controller.run();
SwingUtilities.invokeLater(() -> {
GameOfLifeFrame frame = new GameOfLifeFrame(controller);
frame.init();
});
UI class:
package org.gameoflife.ui;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import org.gameoflife.controller.GOLController;
import org.gameoflife.model.Tile;
public class GameOfLifeFrame extends JFrame {
private final GOLController controller;
private JScrollPane jsp;
public GameOfLifeFrame(GOLController controller) throws HeadlessException {
super("Game of Life");
this.controller = controller;
}
public void init() {
jsp = new JScrollPane();
add(jsp);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setVisible(true);
controller.setLock();
this.draw();
controller.releaseLock();
}
public void draw(){
List<List<Tile>> currentState = controller.getTiles();
GridLayout layout = new GridLayout(currentState.size(), currentState.get(0).size());
JPanel p = new JPanel(layout);
currentState.stream().forEach((currentTiles) -> {
currentTiles.stream().map((t) -> {
JButton b=new JButton(" ");
b.setBackground(t.isHasLife() ? Color.GREEN : Color.BLACK);
return b;
}).forEach((b) -> {
p.add(b);
});
});
jsp.removeAll();
jsp.setViewportView(p);
}
}
I'm probably overlooking something really stupid, any help is appreciated.
This: jsp.removeAll() is going to be problematic, as it's likely removed the viewport AND the JScrollBars, it's also no required, as setting the viewportView will do the same thing anyway
Remember, JScrollPane is a specailsed component, that consists of a JViewPort and two JScrollBars, the actually content lives on the JViewport, not the JScrollPane

How can i make a layout like the attached gif?

My question is about layout in Java Swing.
I want to make a screen like shown below. I saw this video on youtube and made a gif of the part I want.
I want 2 panels and a button like this:
When i clicked the button the JPanel will be hidden and JTable's width will be 100% like html/css like this; (And when button clicked again JPanel will be shown etc..)
How can I do this? Which layout should I use?
There is more than one way to do it, but here's an example that uses BorderLayout as the main layout, and places the button in a left aligning FlowLayout:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
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;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
public class LayoutDemo {
private LayoutDemo() {
JFrame frame = new JFrame("Demo");
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel buttonHolder = new JPanel(new FlowLayout(FlowLayout.LEADING));
frame.add(buttonHolder, BorderLayout.NORTH);
JButton button = new JButton("Toggle visibility");
buttonHolder.add(button);
final JPanel left = new JPanel();
left.setPreferredSize(new Dimension(100, 200));
left.setBackground(Color.BLUE);
frame.add(left, BorderLayout.LINE_START);
JLabel table = new JLabel("This pretends to be a table", SwingConstants.CENTER);
table.setPreferredSize(new Dimension(400, 200));
frame.add(table);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
left.setVisible(!left.isVisible());
}
});
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new LayoutDemo();
}
});
}
}
I used setPreferredSize() to give the components some reasonable default size, but usually it should be automatically calculated by the layout manager from the sizes of the child components, or in case of a custom component, you should override getPreferredSize() return what is appropriate for the component.
The result looks like:

button size and position

Hi I want to put my button at the South position! How can I do that? Here is my code:
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.io.*;
import java.util.*;
import javax.swing.JButton;
public class TableDemo extends JPanel {
private static Icon leftButtonIcon;
private boolean DEBUG = false;
// added static infront becuase got non static referencing error
static List<String[]> rosterList = new ArrayList<String[]>();
public TableDemo() {
super(new GridLayout(1,0));
JTable table = new JTable(new MyTableModel());
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
JButton button=new JButton("Buy it");
button.setSize(30,60);
button.add(button);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Add the scroll pane to this panel.
add(scrollPane);
//create a button
}
class MyTableModel extends AbstractTableModel {
private String[] columnNames = { "Κωδικός", "Ποσότητα", "Τιμή", "Περιγραφή", "Μέγεθος", "Ράτσα"};
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return rosterList.size();
}
#Override
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col)
{
return rosterList.get(row)[col];
}
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
TableDemo newContentPane = new TableDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
Something like this?
See the comments in the code.
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.border.EmptyBorder;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.io.*;
import java.util.*;
import javax.swing.JButton;
public class TableDemo extends JPanel {
private static Icon leftButtonIcon;
private boolean DEBUG = false;
// added static infront becuase got non static referencing error
static List<String[]> rosterList = new ArrayList<String[]>();
public TableDemo() {
super(new BorderLayout(3,3));
JTable table = new JTable(new MyTableModel());
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
JButton button=new JButton("Buy it");
// Rarely has the intended effect.
// also best not to presume we can guess the size
// a component needs to be.
//button.setSize(30,60);
// cannot add a button to itself!
//button.add(button);
JPanel buttonCenter = new JPanel( new FlowLayout(FlowLayout.CENTER) );
// allow the button to be centered in buttonCenter,
// rather than stretch across the width of the SOUTH
// of the TableDemo
buttonCenter.add(button);
add(buttonCenter, BorderLayout.SOUTH);
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Add the scroll pane to this panel.
add(scrollPane, BorderLayout.CENTER);
//create a button
// add a nice border
setBorder(new EmptyBorder(5,5,5,5));
}
class MyTableModel extends AbstractTableModel {
// apologies about the column names
private String[] columnNames = { "??d????", "??s?t?ta", "??µ?", "?e????af?", "???e???", "??tsa"};
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return rosterList.size();
}
#Override
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col)
{
return rosterList.get(row)[col];
}
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("TableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
TableDemo newContentPane = new TableDemo();
// JPanels are opaque by default!
//newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Should be done on the EDT.
// Left as an exercise for the reader.
TableDemo.createAndShowGUI();
}
}
You add the button to itself, and you should use BorderLayout, if you want to place the components in Center / North / South / etc. manners:
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(button, BorderLayout.SOUTH);
"Hi i want to put my button at the South posotion! how can i?"
If you want to place something in a BorderLayout location, it would make sense to have the container use a ... BorderLayout, n'est-ce pas?
But seriously, most of your recent questions in this forum suggest you're coming here before reading the tutorials. You've already been given the links several times, so please do yourself a favor and learn Swing right -- study the layout tutorials and other tutorials and you will save yourself a lot of grief and guessing.
try this:
JFrame frame = new JFrame();
frame.add(yourbutton,BORDERLAYOUT.SOUTH)
and for give position and size to button,do this
yourbutton.setBounds(10,15,120,200) --> (x,y,height,width) , x , y set possition

Categories

Resources