JSplitPane -- can't set maximum size; - java

Been a while since I've been here. I'm learning java and have a question as to why the panel I've created in a JSplitPane can be resized beyond the maximum that I've set:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MainWindow {
//set all components
JFrame frame;
JPanel showPanel;//displays individual contact when clicked on in the contacts panel;
JPanel listPanel;// displays the contactsPanel
JSplitPane contactsSplitPane;
public void buildMainWindow() {// open method
frame = new JFrame("Contacts");
frame.setBackground(Color.WHITE);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
showPanel = new JPanel();
showPanel.setBackground(Color.WHITE);
listPanel = new JPanel();
listPanel.setBackground(Color.LIGHT_GRAY);
listPanel.setMaximumSize(new Dimension (300,1000));
//create SplitPane for the listPanel and showPanel
contactsSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, listPanel,showPanel);
contactsSplitPane.setOneTouchExpandable(true);
contactsSplitPane.setDividerLocation(50);
frame.setSize(1000, 1000);
frame.setVisible(true);
frame.add(BorderLayout.CENTER, contactsSplitPane);
}//close method
public static void main (String [] args) {
MainWindow MainWindow = new MainWindow ();
MainWindow.buildMainWindow();
}
}// close class
feel free to run and compile. I've set the size of the listPanel to a maximum of 300 pixels, but I can resize it way beyond that -- almost to the end of the frame. It's not possible to crate a single resizable pane, no?
Can someone let me know what I'm doing wrong? I'm obviously missing something, but I don't know what.

A JSplitPane doesn't respect the maximum size of either component.
However, it does respect the minimum size of a component.
So one approach could be do set the minimum size on the other component added to the split pane. You will need to override the getMinimumSize() method of this component since the size of the split pane can change dynamically.
Something like:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SplitPaneMaximum extends JPanel
{
JSplitPane splitPane;
public SplitPaneMaximum()
{
setLayout( new BorderLayout() );
JPanel red = new JPanel();
red.setBackground( Color.RED );
red.setPreferredSize( new Dimension(200, 100) );
red.setMinimumSize( new Dimension(100, 0) );
JPanel blue = new JPanel()
{
// Setting a minimum size here will limit the maximum size
// of the other component added to the split pane
#Override
public Dimension getMinimumSize()
{
int parentWidth = getParent().getSize().width;
Dimension d = getSize();
d.width = parentWidth - 200;
return d;
}
};
blue.setBackground( Color.BLUE );
blue.setPreferredSize( new Dimension(200, 100) );
splitPane = new JSplitPane();
splitPane.setLeftComponent( red );
splitPane.setRightComponent( blue );
splitPane.setResizeWeight(0.50);
add(splitPane, BorderLayout.CENTER);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("SplitPaneMaximum");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new SplitPaneMaximum() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Now the width of the red panel can only be sized between 100 and 200 pixels.

Related

Layout manager problems while programming UI

There is a specific UI that I am trying to create for a Java program and I have been having trouble choosing the adequate Layout Managers. I would like my program to have a top panel with three elements (Two JTextFields and one JButton) and a lower JPanel that has another JPanel inside. The inner panel should always be a square, centered according to its container and adapt to the maximum height or width of its container. I have tried using a ComponentAdapter to achieve the effect of always staying a square, but the program does not seem to act the way I want it to, also the top Panel seems to get squeezed to the top
JPanel maincontainer = new JPanel();
maincontainer.setLayout(new BoxLayout(maincontainer, BoxLayout.PAGE_AXIS));
JPanel jpanel2 = new JPanel();
jpanel2.setLayout(new GridLayout(0, 3));
JTextField txt = new JTextField();
txt.setFocusable(false);
JButton btn = new JButton();
btn.setFocusable(false);
JTextField txt2 = new JTextField();
txt2.setFocusable(false);
jpanel2.add(txt);
jpanel2.add(btn);
jpanel2.add(txt2);
maincontainer.add(jpanel2);
JPanel masterPane = new JPanel(new GridBagLayout());
JPanel centerPane = new JPanel();
masterPane.add(centerPane);
masterPane.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
if(masterPane.getHeight()<masterPane.getWidth())
centerPane.setSize(masterPane.getHeight(), masterPane.getHeight());
else
centerPane.setSize(masterPane.getWidth(), masterPane.getWidth());
}
});
centerPane.setBackground(Color.blue);
masterPane.add(centerPane);
maincontainer.add(masterPane);
JFrame frame = new JFrame("");
frame.getContentPane().add(maincontainer);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setMinimumSize(new Dimension(300,300));
frame.setSize(500, 500);
I would like my program to have a top panel with three elements (Two JTextFields and one JButton) and a lower JPanel that has another JPanel inside.
The easiest way to do this is to keep using the default layout manager of the frame which is a BorderLayout. You add the panel with the text fields and buttons to the BorderLayout.PAGE_START. Then you add the panel that changes dynamically to the BorderLayout.CENTER.
The inner panel should always be a square, centered according to its container and adapt to the maximum height or width of its container
The easiest way to center a component on a panel is to use a GridBagLayout on the panel. The default GridBagConstraints will cause the component to be displayed at it preferred size centered both vertically and horizontally. So you will need a wrapper panel using the GridBagLayout to contain your center panel.
You would then want to override the getPreferredSize() method of your center panel to dynamically change as the size of the parent panel changes. This is a better approach than using a ComponentListener.
Something like:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class SSCCE extends JPanel
{
SSCCE()
{
setLayout( new BorderLayout() );
JPanel top = new JPanel( new GridLayout(0, 3) );
top.add( new JTextField(10) );
top.add( new JButton("Button") );
top.add( new JTextField(10) );
add(top, BorderLayout.PAGE_START);
JPanel center = new JPanel()
{
#Override
public Dimension getPreferredSize()
{
Dimension parent = getParent().getSize();
if (parent.width < parent.height)
return new Dimension(parent.width, parent.width);
else
return new Dimension(parent.height, parent.height);
}
};
center.setBackground( Color.BLUE );
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(center, new GridBagConstraints());
add(wrapper, BorderLayout.CENTER);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
static class DragListener extends MouseInputAdapter
{
Point location;
MouseEvent pressed;
public void mousePressed(MouseEvent me)
{
pressed = me;
}
public void mouseDragged(MouseEvent me)
{
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
}
}

Center JLabel On JFrame

I've been reading around lately on centering a JLabel in a JPanel. I've seen a lot of the following two answers:
label.setHorizontalAlignment(JLabel.CENTER);
and in the creation of the JLabel
static JLabel label = new JLabel("Some Text Here", SwingConstants.CENTER);
Neither of these options that I have tried have worked. All the text becomes left alligned with both of these answers (I've even tried using both of them at the same time, and no luck). Here is the full code for one of my labels with its instantiation and everything:
//JLabel title = new JLabel("Title", SwingConstants.CENTER);
JLabel title = new JLabel("Title");
title.setVisible(true);
title.setForeground(Color.BLACK);
title.setFont(new Font("Monospaced", Font.BOLD, 32));
//title.setHorizontalAlignment(JLabel.CENTER);
title.setLocation((int)width/2-190,10);
title.setSize(250,100);
frame.add(title);
I commented out the code that just left aligns it and is supposed to work. For the set location, I'm using:
static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
static double width = screenSize.getWidth();
static double height = screenSize.getHeight();
to define the screen's parameters, and then use that to keep the centering somewhat abstract. However, obviously monitor size changes and 9 times out of 10, the code I have here for setLocation isn't going to center it on your screen.
I'm really curious to why this isn't working for me. Is it because I'm not adding the JLabel to a JPanel? I was under the assumption that JLabel could lay over a JFrame in the same way it layed over a JPanel.
EDIT
I just also tried
frame.add(title,BorderLayout.CENTER);
and had the same result as the other 2 options above.
This works for me (NOTE: SwingConstants.CENTER, not SwingConstraints.CENTER):
public static void main( String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
#Override
public void run() {
JFrame jf = new JFrame();
jf.addWindowListener( new WindowAdapter() {
#Override
public void windowClosing( WindowEvent arg0 ) {
System.exit( 0 );
}
} );
JLabel t = new JLabel( "Centered", SwingConstants.CENTER );
jf.add( t, BorderLayout.CENTER );
jf.setSize( 300, 300 );
jf.setVisible( true );
}
} );
}
Also:
import java.awt.Color;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class CenterDemo2 {
public static void main(final String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
#Override
public void run() {
final JFrame frame = new JFrame("Test frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JLabel label = new JLabel("Test label");
label.setBorder(new LineBorder(Color.BLUE, 2)); //Adding a border for clarity.
//Most significant two lines of code:
final JPanel containerPanel = new JPanel(new GridBagLayout());
containerPanel.add(label);
frame.getContentPane().add(containerPanel); //or: frame.setContentPane(containerPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
The JLabel is in the (horizontal and vertical) center of the JPanel.
Screenshot, after dragging with the mouse to resize the frame:

How would I position a JComponent to true center in a BorderLayout?

I am developing a Swing application using BorderLayout to position the components. Since BorderLayout.CENTER positions components to whatever is left after the other components are placed, and that fact is making my GUI look weird, I was wondering if there was a way to position components to true center, rather than in between the two sides. Since BorderLayout spaces make a component fill an entire space, I'm guessing the solution would be to wrap the component into a JPanel. However, positioning the component to the center of this panel will make the component be closer to one side than another if you have components on other sides. How do I work around this?
These images demonstrate the problem and the ideal solution; the gray border represents the BorderLayout.SOUTH (wrapped in a JPanel) of the main frame. The black squares represents components that are throwing the center component off. The red square represents the component that needs to be centered.
Problem:
Ideal solution:
As I see the problem, in order for the red component to be centered the right and left components must be of equal size.
You might be able to use the Relative Layout.
The RelativeLayout will allow you to make the right/left components the same size while keeping the center component at its preferred size. As the frame is resized space will be added/removed from the right/left components.
For example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
JPanel left = new JPanel( new FlowLayout(FlowLayout.LEFT) );
JPanel leftBox = new JPanel();
leftBox.setPreferredSize( new Dimension(200, 50) );
leftBox.setBackground( Color.BLACK );
left.add( leftBox );
JPanel center = new JPanel( new FlowLayout(FlowLayout.CENTER) );
JPanel centerBox = new JPanel();
centerBox.setPreferredSize( new Dimension(50, 50) );
centerBox.setBackground( Color.RED );
center.add( centerBox );
JPanel right = new JPanel( new FlowLayout(FlowLayout.RIGHT) );
JPanel rightBox = new JPanel();
rightBox.setPreferredSize( new Dimension(50, 50) );
rightBox.setBackground( Color.BLACK );
right.add( rightBox );
setLayout( new RelativeLayout(RelativeLayout.X_AXIS, 5) );
add(left, new Float(1));
add(center);
add(right, new Float(1));
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
The one problem with the relative layout is that when you pack the frame the components will be dislayed too small since the preferred size is simply the sum of the components. So the left panel will be truncated.
In the example above you can add the following to get around this problem:
right.add( rightBox );
right.setPreferredSize( left.getPreferredSize() ); // added
Another option might be to use the OverlayLayout which can be set up to display the red panel over top of a panel containing the two other components:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
JPanel left = new JPanel( new FlowLayout(FlowLayout.LEFT) );
JPanel leftBox = new JPanel();
leftBox.setPreferredSize( new Dimension(200, 50) );
leftBox.setBackground( Color.BLACK );
left.add( leftBox );
JPanel center = new JPanel( new FlowLayout(FlowLayout.CENTER) );
center.setOpaque(false);
JPanel centerBox = new JPanel();
centerBox.setPreferredSize( new Dimension(50, 50) );
centerBox.setBackground( Color.RED );
center.add( centerBox );
JPanel right = new JPanel( new FlowLayout(FlowLayout.RIGHT) );
JPanel rightBox = new JPanel();
rightBox.setPreferredSize( new Dimension(50, 50) );
rightBox.setBackground( Color.BLACK );
right.add( rightBox );
JPanel main = new JPanel( new BorderLayout() );
main.add(left, BorderLayout.LINE_START);
main.add(right, BorderLayout.LINE_END);
setLayout( new OverlayLayout(this) );
add(center);
add(main);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}

Hide the scroll bar, but it continue working

I'm trying to hide the vertical bar of a scrollpane, but I want that it continues scrolling vertically. This is my code:
JScrollPane scroll=new JScrollPane(arbol);
scroll.setBounds(35,40, 230, 530);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setBorder(null);
scroll.setOpaque(false);
scroll.getVerticalScrollBar().setBorder(null);
scroll.getViewport().setOpaque(false);
JLabel sep=new JLabel(Imagen("SeparaV.png"));
sep.setSize(scroll.getSize());
sep.setLocation(-17, 0);
sep.setHorizontalAlignment(JLabel.RIGHT);
scroll.add(sep);
Frame.add(scroll);
For me it is good, if it only shows the arrows. So this is what I need:
for me is good if only show the arrows
I assume you mean you don't want to see the bar in the middle that is used to drag the scrollbar. If so then you can use the default Actions of the scrollbar to create a simple panel with only the arrow buttons:
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
public class ScrollPaneSSCCE extends JPanel
{
public ScrollPaneSSCCE()
{
setLayout( new BorderLayout() );
JTable table = new JTable(50, 5);
JScrollPane scrollPane = new JScrollPane( table );
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
add(scrollPane);
JScrollBar vertical = scrollPane.getVerticalScrollBar();
JPanel east = new JPanel( new BorderLayout() );
add(east, BorderLayout.EAST);
BasicArrowButton north = new BasicArrowButton(BasicArrowButton.NORTH);
north.setAction( new ActionMapAction("", vertical, "negativeUnitIncrement") );
east.add(north, BorderLayout.NORTH);
BasicArrowButton south = new BasicArrowButton(BasicArrowButton.SOUTH);
south.setAction( new ActionMapAction("", vertical, "positiveUnitIncrement") );
east.add(south, BorderLayout.SOUTH);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("ScrollPaneSSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ScrollPaneSSCCE());
frame.setSize(200, 300);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
You will need to check out Action Map Action to understand how this works.

How can I properly center a JPanel ( FIXED SIZE ) inside a JFrame?

Hi all!
I'm trying to solve an -apparently- simple problem, but I cannot fix it.
I'm working on a sample application with Java/Swing libraries;
I have a JFrame and a JPanel.
I just want to achieve the following objectives:
JPanel MUST be centered inside the JFrame.
JPanel MUST have ALWAYS the size that is specified with
setPreferredSize() method. It MUST NOT be resized under this size.
I tried by using a GridBagLayout: it's the ONLY way I can do it.
See the sample below:
/* file StackSample01.java */
import java.awt.*;
import javax.swing.*;
public class StackSample01 {
public static void main(String [] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.setBackground(Color.RED);
frame.setLayout(new GridBagLayout());
frame.add(panel, new GridBagConstraints());
frame.setSize(new Dimension(200, 200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Here a screenshot:
I would not use a GridBagLayout to do a thing too simple.
I tried a simplest solution, by using a Box, but this does not work:
Sample code:
/* file StackSample02.java */
import java.awt.*;
import javax.swing.*;
public class StackSample02 {
public static void main(String [] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.setBackground(Color.RED); // for debug
panel.setAlignmentX(JComponent.CENTER_ALIGNMENT); // have no effect
Box box = new Box(BoxLayout.Y_AXIS);
box.add(Box.createVerticalGlue());
box.add(panel);
box.add(Box.createVerticalGlue()); // causes a deformation
frame.add(box);
frame.setSize(new Dimension(200, 200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Here a screenshot,
Any ideas? Thanks to all :-)
BoxLayout can pretty to hold your setXxxSize(), then just add panel.setMaximumSize(new Dimension(100, 100));
and your output would be
Removed by setMinimumSize(notice if Container has greater size as ... )
import java.awt.*;
import javax.swing.*;
public class CustomComponent12 extends JFrame {
private static final long serialVersionUID = 1L;
public CustomComponent12() {
Box box = new Box(BoxLayout.Y_AXIS);
box.setAlignmentX(JComponent.CENTER_ALIGNMENT);
box.add(Box.createVerticalGlue());
box.add(new CustomComponents12());
box.add(Box.createVerticalGlue());
add(box);
pack();
setTitle("Custom Component Test / BoxLayout");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setMaximumSize(getMinimumSize());
setMinimumSize(getMinimumSize());
setPreferredSize(getPreferredSize());
setLocation(150, 150);
setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
CustomComponent12 main = new CustomComponent12();
}
};
javax.swing.SwingUtilities.invokeLater(r);
}
}
class CustomComponents12 extends JPanel {
private static final long serialVersionUID = 1L;
#Override
public Dimension getMinimumSize() {
return new Dimension(100, 100);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(100, 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
#Override
public void paintComponent(Graphics g) {
int margin = 10;
Dimension dim = getSize();
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
}
}
First of all, thanks to all.
I reply another time to my own question, to show everyone the choice I have made.
See the sample code below;
As you can see, I have included only minimal steps which are absolutely necessary to achieve the goal.
/* file StackResponse.java */
import java.awt.*;
import javax.swing.*;
public class StackResponse {
public static void main(String [] args) {
JPanel panel = new JPanel();
Dimension expectedDimension = new Dimension(100, 100);
panel.setPreferredSize(expectedDimension);
panel.setMaximumSize(expectedDimension);
panel.setMinimumSize(expectedDimension);
panel.setBackground(Color.RED); // for debug only
Box box = new Box(BoxLayout.Y_AXIS);
box.add(Box.createVerticalGlue());
box.add(panel);
box.add(Box.createVerticalGlue());
JFrame frame = new JFrame();
frame.add(box);
frame.setSize(new Dimension(200, 200));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(frame.getMinimumSize()); // cannot be resized-
frame.setVisible(true);
}
}
Here you can see a screenshot.
Problem solved.
Many thanks again to all.
IT
create a panel by name "FixedPanel" with GridBagLayout and set preferred size to frame size
then add your frame into FixedPanel.
Frame = new JFrame("CenterFrame");
Frame.setLocation(0, 0);
Frame.setSize(new Dimension(400,400));//dim
JPanel FixedPanel = new JPanel(new GridBagLayout());
FixedPanel.setPreferredSize(Frame.getSize());
JPanel myPanel = new JPanel();
myPanel.setPreferredSize(new Dimension(100,100));
myPanel.setBackground(Color.BLACK);
FixedPanel.add(myPanel);
Frame.add(FixedPanel);
Frame.setVisible(true);
You can do this. I had to make a chess game, and I wanted the chess piece piece to always go in the center of a cell which was a JlayeredPane:
private void formMouseReleased(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
if (jl != null)
{
jl.setLocation(evt.getX()+10, evt.getY()+10);
Component com = findComponentAt(evt.getPoint());
if (com instanceof JPanel)
{
// System.out.println("Yes, it's a jpanel");
((JPanel)com).add(jl);
((JPanel)com).validate();
}
}
}
Its Just Having
jPanel.setBounds(x, y, 1046, 503);
Where x is space for right side and y is space for left side.
you have to calculate the space from both side according to screen height and width
use
panel.setMaximumSize(new Dimension(200,200));
panel.setResizable(false)
instead?

Categories

Resources