Massive space between components - java

Please have a look at the following code
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridLayoutTest2
{
private final JDialog msgDisplayer;
public GridLayoutTest2()
{
JLabel maleLabel = new JLabel("Male",JLabel.CENTER);
maleLabel.setBorder(BorderFactory.createEmptyBorder());
JLabel femaleLabel = new JLabel("Female",JLabel.CENTER);
femaleLabel.setBorder(BorderFactory.createEmptyBorder());
JLabel fmaleIcon = new JLabel();
fmaleIcon.setIcon(new ImageIcon(getClass().getResource("/images/TESTING-Image.gif")));
fmaleIcon.setBorder(BorderFactory.createEmptyBorder());
JLabel maleIcon = new JLabel();
maleIcon.setIcon(new ImageIcon(getClass().getResource("/images/TESTING-Image.gif")));
maleIcon.setBorder(BorderFactory.createEmptyBorder());
msgDisplayer = new JDialog();
msgDisplayer.setLayout(new GridLayout(4,1,1,1));
msgDisplayer.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
msgDisplayer.setTitle("Body Fat Percentage Classification");
msgDisplayer.add(femaleLabel);
msgDisplayer.add(fmaleIcon);
msgDisplayer.add(maleLabel);
msgDisplayer.add(maleIcon);
msgDisplayer.pack();
msgDisplayer.setVisible(true);
msgDisplayer.setLocationRelativeTo(null);
}
public static void main(String[]args)
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new GridLayoutTest2();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
This code contains a HUGE gap (space) between the labels and images screenshot attached). I do not want to have this space between labels and images. How can I eliminate it? I know I can go with the GridBagLayout to do it, but, is there any way in GridLayout? Please help!

GridLayout allocates an equals amount of space for all components based on the largest component in the container. If you don't wish to use a complex layout manager such as GridBagLayout, you could use BoxLayout, which uses the component's preferred sizes. A BoxLayout with Y_AXIS alignment would be suitable here.
Example

Thats not the gap space, its real size of JLabel's (maleLabel, fmaleLabel). Size of image determines size of parent JLabel and in GridLayout, all components will take size of largest component. Gap between components is 1 as you defined when setting layout. So solution of your problem lays in finding suitable layout manager.
Reimeus gave you an example of GridBagLayout and BoxLayout, and I would like to recommend you MiGLayout which is quite easy to use.

Its the Layout what matters!!
Here I have done a short EG with my GUI builder to show the adjustment of white space(or the size of JLabel):
More white space:
Code:
public class udyfash extends javax.swing.JFrame {
public udyfash() {
initComponents();
}
#SuppressWarnings("unchecked")
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images.jpg"))); // NOI18N
jLabel1.setText("yooo!!");
jLabel1.setBorder(javax.swing.BorderFactory.createCompoundBorder(null, javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 405, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(44, 44, 44)
.addComponent(jLabel1)
.addContainerGap(39, Short.MAX_VALUE))
);
pack();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new udyfash().setVisible(true);
}
});
}
private javax.swing.JLabel jLabel1;
}
We say GridBag is complex,but use the Layout Manager you are ok with.

Related

Problem with GroupLayout: components suddenly "burst" when resizing window

I had a Java assignment about a month ago, which was about building a GUI. I used GroupLayout to manage the position of the components. I ran into a problem where if I put a very long string of text into a JTextField and resize the outer window, the textfield suddenly "bursts".
I fixed the issue using GridBagLayout, but I wanted to come back to the original problem in hopes of getting a better understanding of GroupLayout.
Here's a SSCCE that demonstrates this problem. (I tried to minimize it as much as I can, I apologize if my example is too long.)
import javax.swing.*;
import java.awt.*;
public class Main extends JFrame {
JTextField text1;
JTextField text2;
JPanel myPanel;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(() -> new Main());
}
public Main() {
super("Sussy Imposter");
createComponents();
setLayout();
configureSettings();
}
public void createComponents() {
text1 = new JTextField(20);
text2 = new JTextField(20);
text1.setMaximumSize(text1.getPreferredSize());
text2.setMaximumSize(text2.getPreferredSize());
myPanel = new JPanel();
myPanel.setBackground(Color.CYAN);
myPanel.setPreferredSize(new Dimension(100, 100));
}
public void setLayout() {
Container c = getContentPane();
GroupLayout groupLayout = new GroupLayout(c);
c.setLayout(groupLayout);
groupLayout.setAutoCreateGaps(true);
groupLayout.setAutoCreateContainerGaps(true);
groupLayout.setHorizontalGroup(
groupLayout.createSequentialGroup()
.addComponent(myPanel)
.addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(text1)
.addComponent(text2))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup()
.addComponent(myPanel)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(text1)
.addComponent(text2))
);
}
public void configureSettings() {
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
}
When I copy-paste this text: Let me send you to space 🚀Space travel ASMR Roleplay 🚀(Eng)(Kor) | Roleplay, Storytime, Whitenoise into one of the textfields, and resize the outer window, the textfield "bursts".
I've set the maximum size of the textfields to their preferred sizes in createComponents(), so I don't understand why the size of the textfield exceeds its maximum size when I resize the window.
Can anyone explain why I'm getting this odd behavior?
EDIT: I've overrided the paint() method to see how the width of the textfield size change.
public void paint(Graphics g) {
super.paint(g);
System.out.printf("min: %d\n", text1.getMinimumSize().width);
System.out.printf("pre: %d\n", text1.getPreferredSize().width);
System.out.printf("max: %d\n", text1.getMaximumSize().width);
}
Output before resizing
min: 5
pre: 224
max: 224
Output after resizing
min: 569
pre: 224
max: 224
As #matt pointed out in the comments, this seems to happen because the minimumSize becomes very large. More notably, the minimumSize grows larger than the preferredSize and the maximumSize, which is very unexpected.
Edit:
The behavior of the min size, growing after a resize, and becoming larger than the max size seems like a bug.
Setting the min size explicitly is a workaround it:
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(text1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(text2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
This sets the component min and max size to default size as explained in the documentation:
To make a component fixed size (suppress resizing):
group.addComponent(component, GroupLayout.PREFERRED_SIZE,
GroupLayout.DEFAULT_SIZE,
GroupLayout.PREFERRED_SIZE)
You can achieve the same behavior by setting the min as well as the max sizes:
text1.setMinimumSize(text1.getPreferredSize());
text1.setMaximumSize(text1.getPreferredSize());

Java Swing GUI closing randomly

My problem is quite weird: even if I create a JFrame with literally nothing in it, so it should just display a white window, but it crashes after doing anything with it. For example, when I resize the window, the new, resized area will be black in most cases (or sometimes be the right color I really don't know why) and it will either just close or display "Not responding" and then close after a few seconds.
GUI class:
public class GUI extends JFrame {
private static JFrame frame;
public GUI() {
frame = new JFrame();
frame.setTitle("test");
frame.getContentPane().setLayout(new FlowLayout());
frame.pack();
frame.setVisible(true);
}
}
Main class:
public class Main {
public static void main(String[] args) {
GUI gui = new GUI();
}
}
And here's an image exactly showing the behavior:
Why does it behave like this? It's most definitely not because of the code, I think. It must be something else. I tried reinstalling Java, didn't help out. Switched from SDK 13 to 1.8.0_171, nothing. Older programs using Swing also suddenly don't work anymore and behave the same. Any ideas?
Always start your GUI from the event dispatching thread to avoid unwanted behavior.
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
GUI gui = new GUI();
}
});
}
See the javadoc: invokeLater
Try this (width 400, height 300):
public class GUI extends JFrame {
private static JFrame frame;
public GUI() {
frame = new JFrame();
frame.setTitle("test");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
frame.pack();
frame.setVisible(true);
}
}

How to Hide JPanel and Open another one in other Java FIle?

I'm newbie in java GUI , so i'm facing a problem right now ...
i've created a GUI using Netbeans GUI Builder ..
i've Created a file called MainUI.java and gdUI.Java
the MainUI.java contains the frame and buttons in which if a button is clicked the Jpanel Hides and opens the Panel from gdUI.java
here's the code i've done so far :
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jPanel1.setVisible(false);
}
and gdUI code is :
package GUI;
public class gdUI extends javax.swing.JPanel {
/**
* Creates new form gdUI
*/
public gdUI() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setBackground(new java.awt.Color(255, 153, 51));
setMaximumSize(new java.awt.Dimension(600, 500));
setMinimumSize(new java.awt.Dimension(600, 500));
setPreferredSize(new java.awt.Dimension(600, 500));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 600, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 500, Short.MAX_VALUE)
);
}// </editor-fold>
// Variables declaration - do not modify
// End of variables declaration
}
when i click the button , i successfully hided the current JPanel , how can i add the other files new one ?
Thanks In Advance
The way you want to accomplish this task is using a CardLayout as pointed out by trashgod. This will allow you to switch between views, with simple Cardayout commands like next(), previous() and show(), the last allowing to show any particular component/view by name.
You can see the Oracle tutorial on How to Use CardLayout
You can see How to Use CardLayout with Netbeans GUI Builder
You can see how to drag and drop other panel forms here

Java Dynamic Layout

Im trying to do game in Java: Sudoku. I have some problems with layout.
It's in main class.
GroupLayout layout = new GroupLayout(getContentPane());
GroupLayout layout2 = new GroupLayout(getContentPane());
public void ustawLayout1()
{
this.getContentPane().setLayout(layout);
this.setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
layout.setHorizontalGroup(
layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
.addComponent(etykieta)
.addComponent(latwy)
.addComponent(sredni)
.addComponent(trudny)
.addComponent(start,0,0,450)
)
.addContainerGap(0, 0)
);
layout.setVerticalGroup(
layout.createSequentialGroup()
.addComponent(etykieta)
.addComponent(latwy)
.addComponent(sredni)
.addComponent(trudny)
.addContainerGap(0,Short.MAX_VALUE)
.addComponent(start)
);
}
public void ustawLayout2()
{
this.getContentPane().setLayout(layout2);
layout2.setAutoCreateGaps(true);
layout2.setAutoCreateContainerGaps(true);
layout2.setHorizontalGroup(
layout2.createSequentialGroup()
.addComponent(etykieta2)
.addComponent(zakoncz,0,0,450)
.addContainerGap(0, 0)
);
layout2.setVerticalGroup(
layout2.createSequentialGroup()
.addComponent(etykieta2)
.addContainerGap(0,Short.MAX_VALUE)
.addComponent(zakoncz)
);
}
It's not working and i don't know why.
I would like to do that when i press button "start" layout is changing to layout2.
If you are making a sudoku, try use GridLayout. Its more effective in this case.

Text fields become unresponsive while running Java Swing JFrame after re-opening NetBeans

I created a JFrame form using Java Swing in NetBeans. It contains some text fields, some combo boxes and a button to navigate to the next form. Everything works fine until I close and re-open NetBeans. Now when I run the form only the text fields become unresponsive. The combo boxes and the button work correctly. I tried using setEditable(), setFocusable() and requestFocusinWindow() with the text fields but the output hasn't changed. Please help me.
package Hora.GUI;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class InputJFrame3 extends javax.swing.JFrame
{
public InputJFrame3()
{
initComponents();
numberJTextField.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
numberJTextField.setForeground(Color.black);
}
});
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
numberJLabel = new javax.swing.JLabel();
numberJTextField = new javax.swing.JTextField();
nextJButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("HORA");
setFocusableWindowState(false);
numberJLabel.setText("Number");
nextJButton.setText("next >");
nextJButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nextJButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(nextJButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(numberJLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(numberJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(numberJLabel)
.addComponent(numberJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(nextJButton)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void nextJButtonActionPerformed(java.awt.event.ActionEvent evt)
{
//GEN-FIRST:event_nextJButtonActionPerformed
number=Integer.parseInt(numberJTextField.getText());
Boolean mistake=false;
if(number<1 || number>249)
{
mistake=true;
numberJTextField.setForeground(Color.red);
}
if(!mistake)
setVisible(false);
}//GEN-LAST:event_nextJButtonActionPerformed
public int getNumber()
{
return number;
}
private int number;
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton nextJButton;
private javax.swing.JLabel numberJLabel;
private javax.swing.JTextField numberJTextField;
// End of variables declaration//GEN-END:variables
}
package Hora.GUI;
public class Run
{
public static void main(String[] args)
{
java.awt.EventQueue.invokeLater(new Runnable()
{
public void run()
{
InputJFrame3 frame = new InputJFrame3();
frame.setVisible(true);
}
});
}
}
Your problem is here:
setFocusableWindowState(false);
Doing this prevents the JTextField from getting focus and being usable. I suggest that you not do this.
Also, I agree with camickr, that you should not use an IDE to create your sscce. Just add your components to a simple JPanel which uses FlowLayout by default, something like:
nextJButton.setText("next >");
nextJButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
nextJButtonActionPerformed(evt);
}
});
JPanel panel = new JPanel();
panel.add(numberJLabel);
panel.add(numberJTextField);
panel.add(otherJTextField);
panel.add(nextJButton);
getContentPane().add(panel);
pack();
}// </editor-fold>//GEN-END:initComponents
Also and again, your program looks as if it's swapping JFrames which generally considered a weak design. Instead gear your code to create JPanel "views" and have your GUI swap views with a CardLayout. If you must show a detail window, then use a JDialog.
Edit 2
In a comment you state:
But that part is in the generated code. I opened the java file in Wordpad and modified it. It works now. Is there any other way to do it using the IDE? Thanks a lot Mr. Hovercraft and Mr. Camickr for helping me out. I'm doing this a hobby project for my grandpa who wants to automate his astrology calculations.
I think it is fair to say that most of the main Swing advisers on this site (at least the ones that that I am familiar with) create their Swing code by hand. Don't get me wrong, we use IDE's, but we don't use an IDE's drag-and-drop tool in creating our Swing code. The Swing Tutorials will help you learn how to do this. In particular, please have a look at Lesson: Laying Out Components Within a Container the section.
Note that even if you do end up using a Swing code generator such as NetBeans's Matisse tool, it won't hurt you to learn how to do some hand coding since the knowledge gained will be directly applicable in your work with the code-generating tool.

Categories