Reduce Spaces in a GridLayout Java Swing - java

Good day, please would like to know how to reduce the spaces between the labels and the Textboxes in this picture below and also how to create some spaces between the labels and the frame.Thank you.
My code for this:
private void initUI(JFrame parent) {
// private void initUI() {
myPanel = new JPanel(new GridLayout(3,2,1,1));
buttons_panel = new JPanel(new FlowLayout());
username_label = new JLabel("Username: ");
password_label = new JLabel("Password: ");
username = new JTextField(20);
password = new JPasswordField(20);
ok = new JButton("Ok");
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
cancel = new JButton("Cancel");
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
myPanel.add(username_label);
myPanel.add(username);
myPanel.add(password_label);
myPanel.add(password);
buttons_panel.add(ok);
buttons_panel.add(cancel);
getContentPane().add(myPanel, BorderLayout.CENTER);
getContentPane().add(buttons_panel, BorderLayout.PAGE_END);
pack();
setResizable(false);
setLocationRelativeTo(parent);
}
Should i be using GridBagLayout for this instead?..

All cells in GridLayout have equal size. You have to use GridBagLayout or SpringLayout or BoxLayout.

or use proper
1) Borders
2) set for Alignment (left - right, top - bottom) for
used LayoutManager, simple example for Boxlayout
text alignment (left - center - right)

You can also use the GridLayout hgap and hgap parameters and add a matching, empty Border, as shown here.

Related

How do I switch between different layouts for java swing using a menu?

I want to make an app where I have a JPanel with no default layout. I want to be able to change the layout using options from the menu. For instance, if I have a control to add three image icons to the JPanel , the size and position of these icons should be determined by the frame's current layout manager.
So if I add 3 image icons to a Border Layout (adding them in the South, East and Center positions), switching the layout to a flow layout should make them appear in right to left order with no resizing.
I am confused as to how to go about that. Is there a way to switch layouts within the same JPanel like this?
To dynamically change layouts after each menu action, set the new layout with its constraints and call the revalidate() method. Check the actionPerformed() method of below code.
public class LayoutController extends JFrame implements ActionListener {
JMenuItem flowLayout;
JMenuItem borderLayout;
JMenuItem gridLayout;
JPanel panel;
JButton button1;
JButton button2;
JButton button3;
public LayoutController() {
setSize(600, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new JPanel();
panel.setLayout(null); // no default layout
panel.setSize(600, 600);
flowLayout = new JMenuItem("Flow Layout");
flowLayout.addActionListener(this);
borderLayout = new JMenuItem("Border Layout");
borderLayout.addActionListener(this);
gridLayout = new JMenuItem("Grid Layout");
gridLayout.addActionListener(this);
// menu to change layout dynamically
JMenu fileMenu = new JMenu("Layout");
fileMenu.add(flowLayout);
fileMenu.add(borderLayout);
fileMenu.add(gridLayout);
JMenuBar menuBar = new JMenuBar();
menuBar.add(fileMenu);
setJMenuBar(menuBar);
// Customize your components
button1 = new JButton("IMAGE1");
button2 = new JButton("IMAGE2");
button3 = new JButton("IMAGE3");
panel.add(button1);
panel.add(button2);
panel.add(button3);
add(panel, BorderLayout.CENTER);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new LayoutController().setVisible(true);
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
//Customize your code here
if (e.getSource() == flowLayout) {
//flow layout with right alignment
panel.setLayout(new FlowLayout(FlowLayout.RIGHT));
} else if (e.getSource() == borderLayout) {
// border layout with constraints
BorderLayout layout = new BorderLayout();
layout.addLayoutComponent(button1, BorderLayout.SOUTH);
layout.addLayoutComponent(button2, BorderLayout.EAST);
layout.addLayoutComponent(button3, BorderLayout.CENTER);
panel.setLayout(layout);
} else if (e.getSource() == gridLayout) {
// grid layout with 2 rows and 2 columns
panel.setLayout(new GridLayout(2, 2));
}
panel.revalidate();
}
}

Resizing JPanel containing a JscrollPane having a JTable

I have a JPanel(named mainJP) which has a few buttons and labels (uses BorderLayout). Next it adds another JPanel (named JP1) and inside it a ScrollPane with a JTable. I want to be able to resize JP2 and in turn all its child components (ScrollPane and JTable). So that I can see few more rows of the JTable without having to scroll. Also inorder to resize JP1, other siblings of JP1 should adjust themselves. Not sure how to achieve that.
As the image shows I already have a few features implemented - to entirely delete JP1, to expand/collapse JP1 view, to delete and add rows in the JTable.
So basically I want to be able to drag the mouse at bottom border of JP1 to vertically increase the size of JP1 and its child components (ScrollPane and JTable).
As described in a few of the below solutions, I am still confused at which level should I incorporate a JSpiltPane - as it allows only adding 2 components. I think all the JP1 should be in the JSplitPane. However there can be more than one JP1 components and they are dynamically added.
To add extra components to the JSplitPane is easy. Put a JPanel in each pane you want to show your components, then add the components to this panel -- you can customize the layout as needed.
Something like this will put a JSplitPane in an already create JFrame, add a JPanel to each Pane, and then add some JLabels to the left side, a JTextField to the right. The splitpane will expand to the size of the JFrame it's in.
JSplitPane splitPane = new JSplitPane();
JPanel leftPanel = new JPanel();
JPanel rightPanel = new JPanel();
JLabel label1 = new JLabel();
JLabel label2 = new JLabel();
JTextField textField = new JTextField();
GridBagConstraints gBC = new GridBagConstraints();
getContentPane().setLayout(new GridBagLayout());
leftPanel.setLayout(new GridBagLayout());
rightPanel.setLayout(new GridBagLayout());
// I'm not going to bother doing any layout of the label or textfield here
leftPanel.add(label1, new GridBagConstraints());
leftPanel.add(label2, new GridBagConstraints());
rightPanel.add(textField, new GridBagConstraints());
splitPane.setLeftComponent(leftPanel);
splitPane.setRightComponent(rightPanel);
gBC.fill = GridBagConstraints.BOTH;
gBC.weightx = 1.0;
gBC.weighty = 1.0;
getContentPane().add(splitPane, gBC);
pack();
These are two different problems. Resizing a JPanel on a mouse drag -- the easiest way for you is going to be to use two nested JSplitPanes. You would use one so you can drag horizontally, and another to drag vertically.
Alternatively, if you don't want split panes, you can try something like this method and create a custom JPanel. The borders are there to make the effect more visible. I personally don't like it as it's overly complicated.
public class ResizablePanel extends JPanel {
private boolean drag = false;
private Point dragLocation = new Point();
public ResizablePanel() {
setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
setPreferredSize(new Dimension(500, 500));
final JFrame f = new JFrame("Test");
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
drag = true;
dragLocation = e.getPoint();
}
#Override
public void mouseReleased(MouseEvent e) {
drag = false;
}
});
addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
if (drag) {
if (dragLocation.getX()> getWidth()-10 && dragLocation.getY() > getHeight()-10) {
System.err.println("in");
setSize((int)(getWidth()+(e.getPoint().getX()-dragLocation.getX())),
(int)(getHeight()+(e.getPoint().getY()-dragLocation.getY())));
dragLocation = e.getPoint();
}
}
}
});
f.getContentPane().setLayout(new BorderLayout());
f.getContentPane().add(this,BorderLayout.CENTER);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
new ResizablePanel();
}
public void paintComponent(Graphics g) {
g.setColor(Color.red);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
As for the children resizing with it's parent, that one is pretty easy with GridBagLayout.
The important parts to remember in the GridBagConstraints are the fill, weightx and weighty.
You can just do something like this in your frame -- it will put a scrollpane with a JTable in it that will resize with the frame:
JScrollPane jScrollPane1 = new JScrollPane();
JTable jTable1 = new JTable();
GridBagConstraints gBC = new GridBagConstraints();
getContentPane().setLayout(new GridBagLayout());
jScrollPane1.setViewPortView(jTable1);
gBC.fill = GridBagConstraints.BOTH;
gBC.weightx = 1.0;
gBC.weighty = 1.0;
getContentPane().add(jScrollPane1, gBC);

how to center position progressbar in java

i want my progressbar at the center of the sreen. i already tried...
setLocationRelativeTo(null);
but when i run the program it didnt work. somehow it is not in the middle of the screen. Please help me. See image.
HERE ARE MY CODES
public class progressbar extends JFrame {
private JProgressBar jp;
private Timer t;
int i = 0;
public progressbar() {
setTitle("Loading...");
setDefaultCloseOperation(EXIT_ON_CLOSE);
getContentPane().setLayout(new GridBagLayout());
setLocationRelativeTo(null);
setUndecorated(true);
setVisible(true);
jp = new JProgressBar();
// Paint the percent complete on progress bar
jp.setStringPainted(true);
jp.setPreferredSize(new Dimension(500, 30));
jp.setMinimum(0);
jp.setMaximum(1000);
getContentPane().add(jp);
pack();
// Create a timer that executes for every 2 millisec
t = new Timer(2, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
jp.setValue(i++);
if (i == 1000) {
t.stop();
setVisible(false);
loginInterface l = new loginInterface();
l.txtUser.requestFocus();
}
}
});
// Start the timer
t.start();
}
The GridBagConstraints
Anchor is Center, Grid Height 1, Grid Width 1, Grid X -1, Grid Y - 1
You need to create GridBagConstraints and define anchor (among others like x_weight) to center in GridBagLayout
Then add the component to the layout like this
GridBagLayout layout = new GridBagLayout();
GridBagConstraints cons = new GridBagConstraints();
//set the constraints properties
layout.addLayoutComponent(JProgressBar, cons);
then
setLayout(layout)

JScrollPane behaves unnormally with JTextArea

I asked a question before, on how to make a JTextField insert its text from beneath. Now I got some problem with the code. I edited a little bit, just for testing. Here is the code I'm using right now:
public class BaseTextAreaDemo {
private static JTextArea textArea;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JFrame frame = new JFrame("Base JTextArea App");
final JPanel panel = new JPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
panel.setLayout(new BorderLayout());
JPanel textAreaPanel = getBaseTextArea();
JScrollPane scrollPane = new JScrollPane(textAreaPanel) {
public Dimension getPreferredSize() {
return new Dimension(300, 230);
}
};
panel.add(scrollPane, BorderLayout.SOUTH);
JTextField textField = new JTextField();
textField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
textArea.append(arg0.getActionCommand() + "\n");
}
});
frame.add(panel, BorderLayout.CENTER);
frame.add(textField, BorderLayout.SOUTH);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel getBaseTextArea() {
textArea = new JTextArea();
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.append("bla bla bla\n");
textArea.append("new text here");
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(textArea.getBackground());
panel.setBorder(textArea.getBorder());
textArea.setBorder(null);
panel.add(textArea, BorderLayout.SOUTH);
return panel;
}
});
}
I just added a textField, because I also need one in the program I need this in, and it's useful to add more lines this way.
Now the problem is, when I run this program and I add lines until a vertical scrollbar appears, a horizontal comes out too. I already figured that you can just turn that off, but then some text falls out of the screen. Also, when you make the frame wider, and than return it to it's normal size, the horizontal scrollbar stays at the size from the widened window.
Another problem is that the speed of scrolling is very low in the JTextField.
Try to set the PreferedSize of the textArea to the same as ur JScrollPane:
textArea.setPreferedSize(Dimension(300, 230));
You can aswell just disable Horizontal Scrollbar:
scrollPane.setHorizonalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
You can set the Scrollspeed like this:
scrollPane.getVerticalScrollBar().setUnitIncrement(16);
i could solved the problem: its the panel u are adding to the scrollpane. Add the JTextArea directly to the ScrollPane and the Horizonal Bar only appear if needed:
textArea = new JTextArea();
JScrollPane scrollPane = new JScrollPane(textArea);
if you want to fully remove the horizontal scrollbar then I suggest you invoke this line of code on your JScrollPane:
scrollPane.setHorizonalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

JScrollPane adding JPanels at the top and keeping current scroll view

I have a JScrollPane that contains a vertical Box. I'm inserting new JPanel's at the top of Box. If I use the scrollbar to scroll down I'd like for the current view to remain where I scrolled down to. For example, if I have 50 panels in the box and use the scrollbar to view panel 20, I'd like the view to remain on box 20 even though other boxes are added on top. Additionally, if I use the scrollbar to scroll back up to the top I'd like the view to display new panels as they are added. Any idea how to do this?
BTW, it isn't necessary to use a JScrollPane or a Box. The example code is just to help explain what I am trying to do.
Example code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestScrollPane extends JFrame {
JScrollPane scrollPane;
Box box;
private static int panelCount = 0;
public TestScrollPane() {
setPreferredSize(new Dimension(200, 400));
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.getVerticalScrollBar().setUnitIncrement(15);
box = Box.createVerticalBox();
scrollPane.getViewport().add(box);
this.add(scrollPane);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
Timer t = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
box.add(new TestPanel(), 0);
scrollPane.validate();
}
});
t.setRepeats(true);
t.start();
}
public class TestPanel extends JPanel {
int myId = panelCount++;
public TestPanel() {
this.setLayout(new GridBagLayout());
this.setBorder(BorderFactory.createBevelBorder(1));
JLabel label = new JLabel("" + myId);
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
this.setMaximumSize(new Dimension(100, 100));
this.setPreferredSize(new Dimension(100, 100));
this.add(label);
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
TestScrollPane testScrollPane = new TestScrollPane();
}
});
}
}
EDIT:
This is how I ended up changing the code. I feel somewhat foolish for not seeing the obvious. Anyways, thanx to those that helped.
public void actionPerformed(ActionEvent ae) {
Point view = scrollPane.getViewport().getViewPosition();
TestPanel panel = new TestPanel();
box.add(panel, 0);
scrollPane.validate();
if (view.y != 0) {
view.y += panel.getHeight();
scrollPane.getViewport().setViewPosition(view);
}
}
BTW, I had cross posted this question to http://www.coderanch.com/t/528829/GUI/java/JScrollPane-adding-JPanels-at-top#2398276 Just FYI for those that might care.
You could get the bounds of the component you want to make visible (using JComponent's getBounds method), and use that as an input to JViewPort's scrollRectToVisible method.
Something like:
Timer t = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
TestPanel panel = new TestPanel();
box.add(panel, 0);
JViewport vp = scrollPane.getViewport();
Point p = vp.getViewPosition();
p.y += panel.getPreferredSize().height;
scrollPane.revalidate();
vp.setViewPosition(p);
}
});

Categories

Resources