I just got back into coding, so my apologies for my noobines. I'm trying to create a simple program, with a menu where there is a background, and then in the center is a border, containing two buttons. I've sadly had no idea on how to make my JPanel (background), the background, and have my JPanel (main), just in the center not interfering with anything else.
Here is my code:
package me.niknea.supremeinvasion.menus;
import javax.swing.*;
import java.awt.*;
/**
* Created by Niknea on 7/20/14.
*/
public class Login extends JFrame{
JPanel background, main;
JButton loginButton, registerButton;
public Login(){
super("SupremeInvasion");
selector();
this.setSize(300, 300);
this.setVisible(true);
}//end SimpleGui
public void selector(){
main = new JPanel();
background = new JPanel();
registerButton = new JButton("Register");
loginButton = new JButton("Login");
main.setBackground(Color.LIGHT_GRAY);
background.setBackground(Color.CYAN);
main.add(registerButton);
main.add(loginButton);
main.setBorder(BorderFactory.createLineBorder(Color.BLACK));
main.setBorder(BorderFactory.createTitledBorder(""));
background.setLayout(new BorderLayout());
background.add(main, BorderLayout.CENTER);
this.add(background);
}
}
And a picture of how it looks : http://gyazo.com/e19aa2f86a53ae08e59218e958b766fa, as you can see, the buttons arent centered, nor is the background cyan with only the center being gray with the buttons.
Thanks again,
Niknea.
the buttons arent centered
If you want the buttons horizontally and vertically centered the easiest way is to use a GridBagLayout on the "backgroundPanel".
nor is the background cyan with
That is because the "main" panel completely covers the background panel. Make the "main" panel opaque by using:
main.setOpaque(false);
Try it again after removing below line from your code.
background.setLayout(new GridBagLayout());
and simply add main panel in background panel.
background.add(main);
For further reading, please follow Swing Tutorial on How to Use Various Layout Managers
Is this what you want?
You must set BorderLayout to background. It's default is FlowLayout. You can set a BorderLayout to the panel background and setPreferredSize to the panel main.
background.setLayout(new BorderLayout());
I cannot recommend using GridBagLayout manager. It has many drawbacks.
I have created two examples with MigLayout and GroupLayout.
I am not sure whether the user really needs a separate panel for
the two buttons. (People often seem to think that we need
a panel for such a task when in reality it is not needed.)
But nevertheless I have placed to buttons into a panel and
centered the panel on the window.
Solution with MigLayout
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class CenteredButtons extends JFrame {
public CenteredButtons() {
initUI();
setSize(300, 250);
setTitle("Centered buttons");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
setLayout(new MigLayout("center, center"));
JPanel cpnl = new JPanel();
cpnl.setBorder(BorderFactory.createEtchedBorder());
cpnl.add(new JButton("Register"));
cpnl.add(new JButton("Login"));
add(cpnl);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
CenteredButtons ex = new CenteredButtons();
ex.setVisible(true);
}
});
}
}
Solution with GroupLayout
package com.zetcode;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CenteredButtons2 extends JFrame {
public CenteredButtons2() {
initUI();
setTitle("Centered buttons");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
JPanel cpnl = new JPanel();
cpnl.setBorder(BorderFactory.createEtchedBorder());
cpnl.add(new JButton("Register"));
cpnl.add(new JButton("Login"));
gl.setHorizontalGroup(gl.createSequentialGroup()
.addGap(1, 100, Short.MAX_VALUE)
.addComponent(cpnl, GroupLayout.DEFAULT_SIZE,
GroupLayout.DEFAULT_SIZE,GroupLayout.PREFERRED_SIZE)
.addGap(1, 100, Short.MAX_VALUE)
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addGap(1, 100, Short.MAX_VALUE)
.addComponent(cpnl, GroupLayout.DEFAULT_SIZE,
GroupLayout.DEFAULT_SIZE,GroupLayout.PREFERRED_SIZE)
.addGap(1, 100, Short.MAX_VALUE)
);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
CenteredButtons2 ex = new CenteredButtons2();
ex.setVisible(true);
}
});
}
}
Related
I have a question on my GUI. after I ran my codes. my GUI will display like the picture shown below
But when I enlarged it to full screen. it will become like this.
How do I keep in the center and just like the size in picture one only when enlarged to full screen?
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class GuiTest {
JFrame frame = new JFrame("Gui Test");
JPanel panel = new JPanel(new GridLayout(4,0));
JPanel panelTwo = new JPanel(new BorderLayout());
JLabel labelOne = new JLabel("Text One:");
JLabel labelTwo = new JLabel("Text Two:");
JTextField textFieldOne = new JTextField(15);
JTextField textFieldTwo = new JTextField(15);
JTextField textFieldThree = new JTextField(15);
public GuiTest() {
panel.add(labelOne);
panel.add(textFieldOne);
panel.add(labelTwo);
panel.add(textFieldTwo);
panelTwo.add(panel, BorderLayout.CENTER);
frame.add(panelTwo);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.getPreferredSize();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//frame.setResizable(false);
}
public static void main(String[]args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new GuiTest();
}
});
}
}
Yet another GridLayout confusion!
It is stretching its children and there is nothing that we can do about it.
GridLayout is a very simple manager with very limited practical
usage. Skip it and skip BorderLayout as well. The only thing that
you need to know about BorderLayout is that it is the default manager
of the frame's content pane.
Layout management is a complex thing -- there not shortcuts. One has to
put some effort to learn it. The good news is that there are some very capable
layout managers. I recommend the following two:
MigLayout
GroupLayout
JGoodies' FormLayout is a good option too. These managers are doing
it properly. Study them carefully and choose your favourite.
I provide two solutions, one with MigLayout, one with GroupLayout.
MigLayout solution
MigLayout is a third-party layout manager for which we need to dowload
a single jar file.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class MigLayoutEx extends JFrame {
public MigLayoutEx() {
initUI();
}
private void initUI() {
JPanel pnl = new JPanel(new MigLayout("ins dialog, center, "
+ "center, wrap"));
pnl.add(new JLabel("Text one"));
pnl.add(new JTextField(15));
pnl.add(new JLabel("Text two"));
pnl.add(new JTextField(15));
add(pnl);
pack();
setTitle("MigLayout example");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutEx ex = new MigLayoutEx();
ex.setVisible(true);
}
});
}
}
GroupLayout solution
GroupLayout is a built-in layout manager.
package com.zetcode;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import static javax.swing.GroupLayout.Alignment.LEADING;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
import static javax.swing.GroupLayout.PREFERRED_SIZE;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class GroupLayoutEx extends JFrame {
public GroupLayoutEx() {
initUI();
}
private void initUI() {
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
JLabel lbl1 = new JLabel("Text one");
JLabel lbl2 = new JLabel("Text two");
JTextField field1 = new JTextField(15);
JTextField field2 = new JTextField(15);
gl.setAutoCreateGaps(true);
gl.setAutoCreateContainerGaps(true);
gl.setHorizontalGroup(gl.createSequentialGroup()
.addGap(5, 50, Short.MAX_VALUE)
.addGroup(gl.createParallelGroup(LEADING)
.addComponent(lbl1)
.addComponent(field1, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addComponent(lbl2)
.addComponent(field2, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE))
.addGap(5, 50, Short.MAX_VALUE)
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addGap(5, 50, Short.MAX_VALUE)
.addGroup(gl.createSequentialGroup()
.addComponent(lbl1)
.addComponent(field1, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addComponent(lbl2)
.addComponent(field2, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE))
.addGap(5, 50, Short.MAX_VALUE)
);
pack();
setTitle("GroupLayout example");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GroupLayoutEx ex = new GroupLayoutEx();
ex.setVisible(true);
}
});
}
}
I am relatively new to programming, so I am sorry if this question is stupid. I am creating a Java program that involves one JButton inside a JPanel, and the JPanel is in a JFrame. Another button is outside the JPanel but still in the JFrame. I set the layout to a BoxLayout. My problem is that the the panel, which I made black, is taking up the whole JFrame except for where the second button is. How do I make the JPanel so it is only taking up the area right around the first button?
public class alt {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button1 = new JButton("button 1");
JButton button2 = new JButton("button 2");
public alt(){
frame.setVisible(true);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
panel.setBackground(Color.black);
frame.setTitle("test");
frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
panel.add(button1);
frame.add(panel);
frame.add(button2);
button2.setAlignmentX(Component.CENTER_ALIGNMENT);
}
}
You could make use of a different layout manager, one which gives you more control over deciding how space is allocated and filling is handled, for example, GridBagLayout...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SampleLayout {
public static void main(String[] args) {
new SampleLayout();
}
public SampleLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JPanel panel = new JPanel();
JButton button1 = new JButton("button 1");
JButton button2 = new JButton("button 2");
panel.setBackground(Color.black);
panel.add(button1);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
frame.add(panel, gbc);
frame.add(button2, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Take a look at Laying Out Components Within a Container for more details
The reason why your panel takes up the bulk of the frame's content pane lies
in the way the BoxLayout manager works with the minimum, preferred,
and maximum values of components. It takes the maximum value of a component
into account. And since the maximum value of a JPanel is huge, it takes
all the space available. The solution is to change the maximum value
of a panel. However, this is bad practice. I do not recommend to use
the BoxLayout manager -- it is very weak and leads to poor code.
I recommend to use either the MigLayout manager or the GroupLayout manager.
I provide three solutions: a corrected BoxLayout solution, a MigLayout solution,
and a GroupLayout solution.
BoxLayout solution
We determine the maximum size of the button and change the panel's size
to be a bit larger than the button's.
package com.zetcode;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BoxLayoutPanel extends JFrame {
public BoxLayoutPanel() {
initUI();
}
private void initUI() {
JPanel cpane = (JPanel) getContentPane();
cpane.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
cpane.setLayout(new BoxLayout(cpane,
BoxLayout.Y_AXIS));
JPanel pnl = new JPanel();
JButton btn1 = new JButton("Button 1");
JButton btn2 = new JButton("Button 2");
Dimension dm = btn1.getMaximumSize();
dm.height += 15;
dm.width += 15;
pnl.setMaximumSize(dm);
pnl.setBackground(Color.black);
add(pnl);
add(Box.createVerticalStrut(10));
pnl.add(btn1);
btn2.setAlignmentX(Component.CENTER_ALIGNMENT);
add(btn2);
setTitle("BoxLayout solution");
pack();
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
BoxLayoutPanel ex = new BoxLayoutPanel();
ex.setVisible(true);
}
});
}
}
This is not a clean solution. Generally, we should avoid calling the getMaximumSize() and
the setMaximumSize() in the application code -- this is the layout manager's job. Also in three occasions, we use fixed pixel widths: when we define an empty border, a vertical strut, and a maximum panel's size. This code is however not portable.
Pixel widths change when the resolution of the screen changes. This is a
shortcoming of the BoxLayout manager.
MigLayout solution
This solution is much cleaner and more portable. MigLayout is a third-party
manager, so we need to download additional libraries.
package com.zetcode;
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class MigLayoutPanel extends JFrame {
public MigLayoutPanel(){
initUI();
setTitle("MigLayout solution");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void initUI() {
JPanel main = new JPanel(new MigLayout("center"));
JPanel pnl2 = new JPanel();
JButton btn1 = new JButton("Button 1");
JButton btn2 = new JButton("Button 2");
pnl2.setBackground(Color.black);
pnl2.add(btn1);
main.add(pnl2, "wrap");
main.add(btn2, "alignx center");
add(main);
pack();
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutPanel ex = new MigLayoutPanel();
ex.setVisible(true);
}
});
}
}
GroupLayout solution
GroupLayout is a built-in layout manager. With MigLayout, they are the most
portable and flexible layout managers.
package com.zetcode;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import static javax.swing.GroupLayout.Alignment.CENTER;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
import static javax.swing.GroupLayout.PREFERRED_SIZE;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
public class GroupLayoutPanel extends JFrame {
public GroupLayoutPanel(){
initUI();
setTitle("GroupLayout solution");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
JPanel pnl = new JPanel();
JButton btn1 = new JButton("Button 1");
pnl.add(btn1);
JButton btn2 = new JButton("Button 2");
pnl.setBackground(Color.black);
gl.setAutoCreateGaps(true);
gl.setHorizontalGroup(gl.createSequentialGroup()
.addContainerGap(DEFAULT_SIZE, Integer.MAX_VALUE)
.addGroup(gl.createParallelGroup(CENTER)
.addComponent(pnl, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addComponent(btn2))
.addContainerGap(DEFAULT_SIZE, Integer.MAX_VALUE)
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addContainerGap()
.addComponent(pnl, DEFAULT_SIZE, DEFAULT_SIZE,
PREFERRED_SIZE)
.addPreferredGap(RELATED)
.addComponent(btn2)
.addContainerGap()
);
pack();
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
GroupLayoutPanel ex = new GroupLayoutPanel();
ex.setVisible(true);
}
});
}
}
Attached is my window code:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import java.awt.BorderLayout;
import javax.swing.JTextPane;
public class Window extends JFrame{
private JPanel panel;
private JTextPane textPane;
private JTextPane textPane_1;
public Window() {
super("Window");
this.init();
this.setSize(800, 600);
this.setVisible(true);
}
void init(){
panel = new JPanel();
getContentPane().add(panel, BorderLayout.CENTER);
panel.setLayout(null);
textPane = new JTextPane();
textPane.setBounds(6, 48, 788, 185);
panel.add(textPane);
textPane.setFocusable(true);
textPane_1 = new JTextPane();
textPane_1.setBounds(6, 346, 788, 185);
panel.add(textPane_1);
JScrollPane scroll1 = new JScrollPane(textPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scroll1.setViewportView(textPane);
panel.add(scroll1);
this.add(scroll1);
JScrollPane scroll2 = new JScrollPane(textPane_1, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scroll2.setViewportView(textPane);
panel.add(scroll2);
this.add(scroll2);
this.add(panel);
}
}
My objective is for both JTextPanes to have their own scroll bars. All that appears on the screen though is a single JTextPane (not sure which one), and it has only a vertical scroll bar (I think this is because JTextPanes have word wrap). The second JTextPane isn't showing up. Can anyone help me?
Thanks in advance to all who reply.
You can use GridLayout in this case. See Swing Tutorial on How to Use GridLayout
Here is the code with GridLayout along with inline comments.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
public class MyWindow extends JFrame {
private JPanel panel;
private JTextPane textPane;
private JTextPane textPane_1;
public MyWindow() {
super("Window");
this.init();
}
void init() {
// panel with GridLayout having 2 rows and 1 column
panel = new JPanel(new GridLayout(2,1));
textPane = new JTextPane();
// enclose the text pane inside the scroll pane
// scroll pane shows scrollbars when needed
JScrollPane scroll1 = new JScrollPane(textPane);
// add scroll pane at first column of the first row
// never add text pane again in the panel because
// it's already added in scroll pane
panel.add(scroll1);
textPane_1 = new JTextPane();
JScrollPane scroll2 = new JScrollPane(textPane_1);
// add scroll pane at first column of the second row
panel.add(scroll2);
// finally add the panel in the JFrame's content pane in the center
getContentPane().add(panel, BorderLayout.CENTER);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
MyWindow window=new MyWindow();
window.setVisible(true);
}
});
}
}
snapshot:
Please have a look at Swing Tutorial on How to Use Various Layout Managers
Two points to start with, first, JFrame uses a BorderLayout by default, a BorderLayout only allows a single component to occupy any one of its five available positions. Second a component can only belong to a single parent
Taking a look at your code...
scroll1.setViewportView(textPane);
panel.add(scroll1);
this.add(scroll1);
//...
scroll2.setViewportView(textPane);
panel.add(scroll2);
this.add(scroll2);
this.add(panel);
You set textPane as the viewport view for scroll1
You add scroll1 to panel
You add scroll to this, effectively removing it from panel...
You set textPane as the viewport view of scroll2, removing it from the viewport for scroll1
You add scroll2 to the panel
You add scroll2 to this, effectively removing it from panel...
You add panel to this, overriding everything that was added to the frame previously...
This effectively means that panel is the only visible component the BorderLayout will try to layout on the frame, but it contains nothing
Instead, you could specify a position for each scroll pane when adding it to the frame, for example..
scroll1.setViewportView(textPane);
this.add(scroll1, BorderLayout.NORTH);
//...
scroll2.setViewportView(textPane_1);
this.add(scroll2, BorderLayout.SOUTH);
Updated with working example
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Window extends JFrame {
private JTextPane textPane;
private JTextPane textPane_1;
public Window() {
super("Window");
this.init();
this.setSize(800, 600);
this.setVisible(true);
}
void init() {
textPane = new JTextPane();
textPane_1 = new JTextPane();
JScrollPane scroll1 = new JScrollPane(textPane);
scroll1.setViewportView(textPane);
JScrollPane scroll2 = new JScrollPane(textPane_1);
add(scroll1, BorderLayout.NORTH);
add(scroll2, BorderLayout.SOUTH);
}
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) {
ex.printStackTrace();
}
Window frame = new Window();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
This is the default behaviour for a JTextPane, it's overall size is determine by the size of it's content...
Now, you can make suggestions to the scrollpane about how much space your component would like to use by using the Scrollable interface and specifying the "initial", PreferredScrollableViewportSize...
Lucky for you, JTextPane already implements this interface, so you only need to override the getPreferredScrollableViewportSize method, for example...
textPane = new JTextPane() {
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(200, 200);
}
};
textPane_1 = new JTextPane() {
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(200, 200);
}
};
Take a look at Laying Out Components Within a Container for more details
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
I am new to java, and learning new things everyday.
Today i stumbled upon an error i just can not get fixed.
So i've got a JFrame with a JPanel inside, now I want to remove the Jpanel when i click on my Start game JLabel, and make it transition into my game JPanel ( for now i use a test JPanel)
JFrame class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MainMenu extends JFrame {
JPanel panel;
JFrame frame;
JButton playlabel;
public void mainmenu() {
frame = new JFrame();
panel = new JPanel();
playlabel = new JButton ("Nieuw Spel");
//frame
frame.setSize(new Dimension(800, 600));
frame.getContentPane().setBackground(new Color(14,36,69));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(frame.getMinimumSize());
frame.setVisible(true);
//panel
Dimension expectedDimension = new Dimension(690, 540);
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setPreferredSize(expectedDimension);
panel.setMaximumSize(expectedDimension);
panel.setMinimumSize(expectedDimension);
panel.setBackground(new Color(14, 36, 69));
panel.add(playlabel);
playlabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
//playlabel
playlabel.setFont(new Font("Old English Text MT", Font.BOLD, 40));
playlabel.setBounds(250, 350, 50, 20);
playlabel.setForeground(new Color(217,144,39));
playlabel.setBackground(new Color(14,36,69));
playlabel.setBorderPainted(false);
playlabel.setFocusPainted(false);
playlabel.addActionListener(new PlayListener());
}
private class PlayListener extends JFrame implements ActionListener {
public void actionPerformed(ActionEvent e) {
JPanel panelgame = Game.Game();
this.remove(panel);
this.add(panelgame);
this.revalidate();
}
}
}
Game class:
package labyrinthproject.View;
import java.awt.Color;
import javax.swing.JPanel;
public class Game {
public static JPanel Game(){
JPanel panel = new JPanel();
panel.setSize(690, 540);
panel.setBackground(new Color(255,36,69));
return panel;
}
}
if anyone could explain this to me why this doesn't work, it would be greatly appreciated!
Thank you very much!
Sincerely,
A beginner java student.
There are quite some issues in your code
Create the GUI on the event dispatch thread
Don't extend JFrame (you have three (three!) JFrames floating around there!)
Follow the naming conventions
Don't overuse static methods
Only store the instance variables that you really need to represent your class state
Don't use manual setSize or setBounds calls. Use a LayoutManager instead
The call to frame.setVisible(true) should be the last call, after the frame has been completely assembled
Consider a CardLayout for switching between panels ( http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html )
Slightly cleaned up, but the exact structure depends on what you actually want to achieve at the end:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MainMenu extends JPanel
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame mainFrame = new JFrame();
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainMenu = new MainMenu();
mainFrame.getContentPane().add(mainMenu);
mainFrame.pack();
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
}
MainMenu()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
Dimension expectedDimension = new Dimension(690, 540);
setPreferredSize(expectedDimension);
setBackground(new Color(14, 36, 69));
JButton newGameButton = new JButton ("Nieuw Spel");
newGameButton.setAlignmentX(JComponent.CENTER_ALIGNMENT);
newGameButton.setFont(new Font("Old English Text MT", Font.BOLD, 40));
newGameButton.setForeground(new Color(217,144,39));
newGameButton.setBackground(new Color(14,36,69));
newGameButton.setBorderPainted(false);
newGameButton.setFocusPainted(false);
newGameButton.addActionListener(new PlayListener());
add(newGameButton);
}
private class PlayListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
removeAll();
GamePanel gamePanel = new GamePanel();
add(gamePanel);
revalidate();
}
}
}
class GamePanel extends JPanel
{
GamePanel()
{
setBackground(new Color(255,36,69));
}
}
You should use a JButton and not a JLabel. Then:
you add to your JButton : Your_JB.addActionListener(this); (don't forget to implement ActionListener to your class).
Now, we are gonna add the detector:
#Override
public void actionPerformed(ActionEvent e){
Object src = e.getSource();
if(src == Your_JB){
panel.setVisible(false);
}
}
When you click the button, it will make your panel disapear.
Try this:
this.remove(panel);
this.validate();
this.repaint(); //if you use paintComponent
this.add(panelgame);
this.revalidate();
Swing is hard to making nice UI. You just need to use validate() after remove().
I hope it's helpfull.
Could anyone point out where I am going wrong with this java swing gui code. I am trying to add two buttons to a JPanel and then add it into a frame after setting the size but it seems to not be responding to the setSize values passed to it
public Test() {
GridLayout layout = new GridLayout(1, 2);
//this.setLayout(layout);
this.setSize(700, 700);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel = new JPanel();
buttonPanel.setSize(new Dimension(30, 100));
JButton rectButton = new JButton("Rectangle");
JButton ovalButton = new JButton("Oval");
buttonPanel.add(rectButton);
buttonPanel.add(ovalButton);
this.add(buttonPanel);
this.add(new PaintSurface());
this.setVisible(true);
}
This may not answer your immediate question...but...
GridLayout layout = new GridLayout(1, 2);
this.setLayout(layout);
// You're original code...
// Why are you using `BorderLayout.CENTER` on a `GridLayout`
this.add(new PaintSurface(), BorderLayout.CENTER);
You set the layout as a GridLayout, but you are using BorderLayout constraints to apply one of the components??
Also, make sure that there are not calls to Test#pack else where in your code, as this will override the values of setSize
UPDATED (from changes to question)
Remember, the default layout manager for JFrame is BorderLayout, so even though you're calling buttonPanel.setSize, it's likely that it's begin overridden by the layout manager anyway.
I would take a read through A Visual Guide to Layout Managers and Using Layout Managers to find a layout manager that best meets your requirements.
If you can't find a single one, consider using compound components with different layout managers to bring the layout closer to what you want to achieve.
Ok, I'll just give you a solution:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Cobie extends JFrame{
JButton rectButton = new JButton("Rectangle");
JButton ovalButton = new JButton("Oval");
JPanel buttonPanel = new JPanel();
JPanel paintSurface = new JPanel();
public Cobie(){
setLayout(new GridLayout(2,1));
buttonPanel.setBackground(Color.RED);
paintSurface.setBackground(Color.BLUE);
buttonPanel.add(rectButton);
buttonPanel.add(ovalButton);
add(buttonPanel);
add(paintSurface);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
public void run(){
Cobie c = new Cobie();
c.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
c.setSize(600,400); //Avoid using this method
c.setVisible(true);
}
});
}
}
According to your updated answer, you are not setting your layout on anything.
Anyway, if you use LayoutManager's (which you should), it is pointless to call setSize()/setBounds()/setLocation() since it will be overriden by the LayoutManager (that is actually its job).
And guessing that your Test class extends JFrame, by calling this.add(buttonPanel); this.add(new PaintSurface()); you are adding two components with the same constraint (BorderLayout.CENTER, since BorderLayout is the default LayoutManager of the content pane of the JFrame) to the content pane.
Consider reading the LayoutManager tutorial.
Just for information, although far from perfect, this shows something "working":
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test extends JFrame {
private JPanel buttonPanel;
public class PaintSurface extends JButton {
public PaintSurface() {
super("Paint surface dummy");
}
}
public Test() {
GridLayout layout = new GridLayout(1, 2);
this.setLayout(layout);
this.setSize(700, 700);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buttonPanel = new JPanel();
buttonPanel.setSize(new Dimension(30, 100));
JButton rectButton = new JButton("Rectangle");
JButton ovalButton = new JButton("Oval");
buttonPanel.add(rectButton);
buttonPanel.add(ovalButton);
this.add(buttonPanel);
this.add(new PaintSurface());
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
}