I am currently working on a short Java Swing project using Eclipse (Luna, Win 8.1). The aim is to display a frame that contains a menu. The menu has different pages (Main, Options, etc.), realized by JPanels with Buttons, Labels, etc. Those JPanels are organized by a CardLayout, in such a manner that calling the CardLayout.show(..)-method switches between different menu pages. When I stopped programming two days ago, everything was working perfectly. However, when I wanted to continue yesterday morning, my code seemed to completely ignore the CardLayout: Buttons situated in other cards would pop up through the first card's background when moving the mouse cursor over their positions. I tried to fix that (researching, using backups, etc.) for 17 hours straight. The problem still persists and I am pretty desperate by now =/. The following SSCCE shows the same behaviour (move mouse over bottom left corner to see the "Option" card's "Back" button pop up).
package sscce;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
private CardLayout mainWindowLayout;
// mainPanel will be used as the MainFrame's main unit to manage Components
private JPanel mainPanel;
// Constructor
public MainFrame() {
setTitle("sscce");
setPreferredSize(new Dimension(800, 600));
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
mainPanel = new JPanel();
mainPanel.setPreferredSize(getSize());
mainWindowLayout = new CardLayout();
mainPanel.setLayout(mainWindowLayout);
buildMainMenu();
buildOptions();
getContentPane().add(mainPanel);
mainPanel.setVisible(true);
// starting application it will "show" (container,
// contentIdentifier(String))
mainWindowLayout.show(mainPanel, "2");
pack();
setVisible(true);
}// Constructor
private void buildMainMenu() {
JPanel panelMainMenu = new JPanel(new GridBagLayout());
panelMainMenu.setBackground(Color.orange);
// 1 Button (centered) to go to Options-Card
JButton bnOptions = new JButton("Options");
// Button Functionality
bnOptions.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
mainWindowLayout.show(mainPanel, "2");
}
});
panelMainMenu.add(bnOptions);
panelMainMenu.setOpaque(true);
// container content identifier(String)
mainPanel.add(panelMainMenu, "1");
panelMainMenu.setVisible(true);
}// buildMainMenu
private void buildOptions() {
JPanel panelOptions = new JPanel();
panelOptions.setLayout(new GridBagLayout());
// standardized margins for all Elements:
final Insets gbcInsets = new Insets(5, 5, 5, 5);
panelOptions.setBackground(Color.white);
JPanel fillerRight = new JPanel();
JPanel fillerTop = new JPanel();
JButton bnOptBack = new JButton("Back");
bnOptBack.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
mainWindowLayout.show(mainPanel, "1");
}
});
// add filler panels to keep button in position
fillerRight.setBackground(Color.red);
fillerRight.setOpaque(true);
panelOptions.add(fillerRight, new GridBagConstraints(1, 1, 1, 2, 1, 0,
GridBagConstraints.NORTH, GridBagConstraints.BOTH, gbcInsets,
0, 0));
fillerRight.setVisible(true);
fillerTop.setBackground(Color.pink);
fillerTop.setOpaque(true);
panelOptions.add(fillerTop, new GridBagConstraints(0, 0, 2, 1, 0, 1,
GridBagConstraints.NORTH, GridBagConstraints.BOTH, gbcInsets,
0, 0));
fillerTop.setVisible(true);
// 1 Button in lower left hand corner, sends you back to MainMenu-card
panelOptions.add(bnOptBack, new GridBagConstraints(0, 1, 1, 1, 0, 0,
GridBagConstraints.NORTH, GridBagConstraints.BOTH, gbcInsets,
0, 0));
bnOptBack.setVisible(true);
panelOptions.setOpaque(true);
// container content identifier(String)
mainPanel.add(panelOptions, "2");
panelOptions.setVisible(true);
}// buildOptions
public static void main(String[] args) {
MainFrame m = new MainFrame();
}// main
}// MainFrame
Any help is greatly appreciated.
Thanks in advance :)
Edit: I guess you don't need to look at the "buildMainMenu" and "buildOptions" methods too closely, the setup for the single menu pages seems to work fine.
It works as expected on my machine when I comment out the following two lines
panelOptions.setVisible(true);
and
panelMainMenu.setVisible(true);
When using the CardLayout, you just add the components and use CardLayout#show to decide which one you show. Calling setVisible first seems to cause problems (for whatever reason).
Making sure that the Swing code is triggered on the EDT is also a good idea:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MainFrame m = new MainFrame();
}
});
Related
I'm having issues with my code regarding the fact that when I instantiate my City class as an object and add it to the right side of my JSplitPane (or even the left), the circle that is supposed to be drawn is not showing up. My cities class uses paintComponent and should draw a circle just by calling the constructor. I have also tried putting the repaint in its own drawIt() method but the result is still the same. The buttons and spinner show up on the left side of the divider, but the circle I am trying to draw does not show up at all.
Here is my City class.
import javax.swing.*;
import java.awt.*;
public class City extends JPanel{
int xPos, yPos;
City(int x, int y){
xPos = x;
yPos = y;
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillOval(xPos, yPos, 10, 10);
}
}
And here is my main.
Here I try to instantiate my city and add it to the right side of the JSplitPane (under Add Components) and that is where I am having issues with, as the black circle will not be drawn on the JSplitPane.
import java.awt.*;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
public class TSP{
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TSP();
}
});
}
TSP(){
JLabel instructions = new JLabel("Enter the number of cities: ");
instructions.setBounds(30, 150, 300, 40);
SpinnerNumberModel numMod = new SpinnerNumberModel(2, 2, 10, 1);
JSpinner numOfCities = new JSpinner(numMod);
numOfCities.setBounds(185, 150, 80, 40);
JButton start = new JButton("Start Simulation");
start.setBounds(50, 400, 200, 40);
JFrame frame = new JFrame("Travelling Salesperson");
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
JPanel lp = new JPanel(null);
JPanel rp = new JPanel(null);
sp.setDividerLocation(300);
sp.setLeftComponent(lp);
sp.setRightComponent(rp);
sp.setEnabled(false);
frame.setDefaultCloseOperation(3);
frame.setSize(1100,600);
frame.setResizable(false);
////////////////Add Components//////////////////////////
lp.add(instructions);
lp.add(numOfCities);
lp.add(start);
City test = new City(301, 301);
rp.add(test);
frame.add(sp);
////////////////////////////////////////////////////////
frame.setVisible(true);
}
}
I feel like the circle is being drawn under the JSplitPane as if I add my cities object (test) to my frame instead of the JSplitPane(frame.add(test) instead of rp.add(test) under the Add Components section) the black circle will appear in the desired spot but the JSplitPane along with the buttons and spinners will disappear so I feel as if they are conflicting. Is there any fix to this or is there another way altogether to make the circle appear on the right side while the other components are on the left side.
I do not know why it is not drawing the circle on the JSplitPane, but any sort of help would be appreciated. Thanks!
Sorry if anything is unclear or there is any ambiguity in my code, or if I need to post more information as I am quite new to posting here. Let me know if there is anything else I need to add or if there are any questions regarding what I am asking!
EDIT:
It seems there is something blocking where I draw the circle, like another JPanel. Here is an image below. As you can see part of the circle looks as if it is being covered. The small box I drew is the only area that the dot is visible from (everywhere else the circle is covered up by white). Also, the coordinates for the circle in the image below is at (3, 0), i.e City test = new City(3, 0);
I am not quite sure why this is happening though.
the invisible JPanel?
Now that I've seen what you're trying to do, I can provide a more proper answer.
You have a control panel on the left and a drawing panel on the right. Usually, you don't use a JSplitPane to separate the panels. To create your layout, you would add the control panel to the LINE_START of the JFrame BorderLayout and the drawing panel to the CENTER.
The reason for this is that you don't want to constantly recalculate the size of the drawing panel.
So let me show you one way to get a solid start. Here's the GUI I created.
Here are the things I did.
All Swing GUI applications must start with a call to the SwingUtilities invokeLater method. This method ensures that Swing components are created and executed on the Event Dispatch Thread.
I separated the creation of the JFrame, the control panel, and the drawing panel. That way, I could focus on one part of the GUI at a time.
The JFrame methods must be called in a certain order. This is the order that I use for most of my Swing applications.
The JFrame is not sized. It is packed. The Swing layout managers will calculate the size of the components and the JPanels.
I used a FlowLayout and a GridBagLayout to create the control panel. Yes, this looks more complicated than absolute positioning, but in the long run, layout managers allow the GUI to be more flexible.
I used the setPreferredSize method in the drawing panel to set the preferred size of the drawing panel. Because I know the drawing panel size, I can put the first city in the center of the drawing panel.
And here's the code. You don't have to code exactly like this, but this code should give you a good basis to start your project. Take a look at the model / view / controller pattern and see how to further separate your code into smaller pieces that allow you to focus on one part of your application at a time.
I put all the classes in one file to make it easier to paste. You should separate these classes into separate files.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
public class CitySimulation implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new CitySimulation());
}
private ControlPanel controlPanel;
private DrawingPanel drawingPanel;
private JFrame frame;
#Override
public void run() {
frame = new JFrame("Traveling Salesperson");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
controlPanel = new ControlPanel();
frame.add(controlPanel.getPanel(), BorderLayout.LINE_START);
drawingPanel = new DrawingPanel();
frame.add(drawingPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class ControlPanel {
private JPanel panel;
public ControlPanel() {
panel = new JPanel(new FlowLayout());
JPanel mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10, 10, 10, 10);
JLabel instructions = new JLabel("Enter the number " +
"of cities:");
mainPanel.add(instructions, gbc);
gbc.gridx++;
gbc.insets = new Insets(10, 0, 10, 10);
SpinnerNumberModel numMod =
new SpinnerNumberModel(2, 2, 10, 1);
JSpinner numOfCities = new JSpinner(numMod);
mainPanel.add(numOfCities, gbc);
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 2;
gbc.insets = new Insets(10, 10, 10, 10);
JButton start = new JButton("Start Simulation");
mainPanel.add(start, gbc);
panel.add(mainPanel);
}
public JPanel getPanel() {
return panel;
}
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
public DrawingPanel() {
this.setBackground(Color.WHITE);
this.setPreferredSize(new Dimension(400, 400));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillOval(195, 195, 10, 10);
}
}
}
I built a great GUI using the frowned upon null layout (I defined a lot of constants and used a window resize listener to make it easy). Everything worked perfectly until I started using a new computer. Now, the component's are not positioned properly (from the picture you can see that the components are offset down and right). After researching the problem I learned that layout managers make sure that the components are positioned properly throughout different machines. Because of this, I would like to start rebuilding the GUI in an actual layout manager. The problem is that I often feel limited in the way I position components when attempting to use an actual layout manager.
For anyone who is curious, I was originally using a dell inspiron laptop with windows 10, and have moved to an Asus Laptop (I don't know the actual model, but the touch screen can detach from the keyboard), also with windows 10.
My question:
Which layout manager would be the fastest and easiest to build the GUI shown in the picture above (out of the stock Swing Layouts and others). I would like this layout to respect the components' actual sizes for only a few but not all of the components. Using this layout, how would I go about positioning the inventory button (the hammer at the bottom left) so that the bottom left corner of the inventory button is 5 pixels up and right from the bottom left corner of the container, even after resizing the container?
Thanks in advance. All help is appreciated.
EDIT: The "go find a key" and "Attempt to force the door open" options should have their sizes respected.
The simplest solution that comes to my mind is a BorderLayout for the main panel. Add the textarea to NORTH / PAGE_START. Make another BorderLayout containing the inventory button (WEST / LINE_START) and the location label (EAST / LINE_END). Add that to SOUTH / PAGE_END of the main BorderLayout. Then just add a BoxLayout with vertical alignment to the main BorderLayout's CENTER containing the two buttons. Here's a tutorial for the standard layout managers.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Example {
public Example() {
JTextArea textArea = new JTextArea("There is a locked door");
textArea.setRows(5);
textArea.setBorder(BorderFactory.createLineBorder(Color.GRAY));
textArea.setEditable(false);
WhiteButton button1 = new WhiteButton("Go find a key") {
#Override
public Dimension getMinimumSize() {
return new Dimension(200, 25);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 25);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(200, 25);
}
};
WhiteButton button2 = new WhiteButton("Attempt to force the door open");
button2.setMargin(new Insets(0, 60, 0, 60));
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS));
buttonPanel.add(button1);
buttonPanel.add(Box.createVerticalStrut(5));
buttonPanel.add(button2);
WhiteButton inventoryButton = new WhiteButton(
new ImageIcon(new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB)));
JLabel locationLabel = new JLabel("Location: 0");
locationLabel.setVerticalAlignment(JLabel.BOTTOM);
JPanel southPanel = new JPanel(new BorderLayout());
southPanel.add(inventoryButton, BorderLayout.WEST);
southPanel.add(locationLabel, BorderLayout.EAST);
JPanel mainPanel = new JPanel(new BorderLayout(0, 5));
mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
mainPanel.add(textArea, BorderLayout.NORTH);
mainPanel.add(buttonPanel);
mainPanel.add(southPanel, BorderLayout.SOUTH);
JFrame frame = new JFrame("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
private class WhiteButton extends JButton {
public WhiteButton() {
setBackground(Color.WHITE);
}
public WhiteButton(String text) {
this();
setText(text);
}
public WhiteButton(ImageIcon icon) {
this();
setIcon(icon);
setBorder(BorderFactory.createLineBorder(Color.GRAY));
}
}
}
This question already has answers here:
Java Swing : why must resize frame, so that can show components have added
(2 answers)
Closed 9 years ago.
I've been rebuilding an old MS-paint copy cat that I did a few months ago, and Swing has once again been giving me some old problems. One of which has had me and a few other people stumped for a few days now. I've got a custom JFrame that I'm using to lay all of my components on, and custom JButtons that are used to represent the various colors and tools that the user can choose from. Right now, the problem is that my program isn't displaying most of my buttons. Here's my ColorButton class:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
public class ColorButton extends JButton implements ActionListener
{
private static final long serialVersionUID = 1L;
Color color;
public ColorButton(Color color, String name)
{
this.color = color;
setButtonIcon(name);
}
private void setButtonIcon(String name)
{
ImageIcon icon = new ImageIcon("images/" + name);
setIcon(icon);
System.out.println("Icon set.");
}
#Override
public void actionPerformed(ActionEvent event)
{
}
}
Basically, this class is just a better button that I could reuse and dynamically place onto the main frame. I have it set up so that it takes a Color (to set the user's cursor color) and a string (in order to get the ImageIcon from the resources folder). Here's the JFrame that I have to add everything to.
import java.awt.BorderLayout;
import java.awt.Color;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
public class PaintFrame extends JFrame // Frame to place all items on
{
private static final long serialVersionUID = 1L;
public PaintFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Set the program to close if the user wishes
setVisible(true); // Set screen to visible
setSize(1150, 650); // Set screen size
setLocationRelativeTo(null); // Set frame to start in middle of screen
setResizable(false);
setLayout(new BorderLayout()); // Set a suitable layout for the panel
setTitle("Paint 2.0");
addComponents(); // Add everything to the JFrame
}
// List to hold all of the color buttons
ArrayList<ColorButton> colorButtons;
private void createColorButtons() // Create and add all color buttons
{
colorButtons = new ArrayList<ColorButton>();
colorButtons.add(new ColorButton(Color.BLACK, "black_paint.png"));
colorButtons.add(new ColorButton(Color.WHITE, "white_paint.png"));
// colorButtons.add(new ColorButton(new Color(22, 10, 255), "blue_paint.png"));
// colorButtons.add(new ColorButton(new Color(163, 92, 45), "brown_paint.png"));
// colorButtons.add(new ColorButton(new Color(19, 175, 50), "dark_green_paint.png"));
// colorButtons.add(new ColorButton(new Color(22, 255, 34), "green_paint.png"));
// colorButtons.add(new ColorButton(new Color(58, 209, 255), "light_blue_paint.png"));
// colorButtons.add(new ColorButton(new Color(255, 84, 33), "orange_paint.png"));
// colorButtons.add(new ColorButton(new Color(255, 86, 243), "pink_paint.png"));
// colorButtons.add(new ColorButton(new Color(168, 11, 121), "purple_paint.png"));
// colorButtons.add(new ColorButton(new Color(255, 0, 0), "red_paint.png"));
// colorButtons.add(new ColorButton(new Color(255, 241, 45), "yellow_paint.png"));
colorButtons.add(new ColorButton(Color.WHITE, "eraser.png"));
}
JPanel colorButtonPanel;
private void addComponents() // Add all the components to the screen
{
createColorButtons();
colorButtonPanel = new JPanel();
colorButtonPanel.setLayout(new BoxLayout(colorButtonPanel,
BoxLayout.X_AXIS));
colorButtonPanel.setBorder(new TitledBorder("Colors & Tools"));
for (ColorButton button : colorButtons)
{
colorButtonPanel.add(button);
}
// Add Panels
add(BorderLayout.SOUTH, colorButtonPanel);
}
}
So, as you can see, the class inherits from JFrame, and all the components are added to the frame in addComponents(). The method that I believe the problem lies in is in createColorButtons(). Right now, all the buttons that aren't displaying are commented out and the other ones are the only buttons that work. The problem here is very specific. If I start the program with any button implemented that doesn't work (ie. any colorButtons.add(foo) that is commented out), then the frame comes up completely empty. None of the buttons appear, just a blank frame. However, if I start the program with all of those buttons commented out, then I can still get the three buttons.
The only thing that is different from these buttons versus the others is that the buttons that won't display use custom created colors, while others use pre-set colors included in the Java API. I can't think of any reason why that should cause any problem, but let me know if you think otherwise. Also let me know if you need any more details, code, or anything else that you can think of that might help you answer the question. Thanks.
Added Main Method for added measures:
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Start // Start the program
{
public static void main(String[] args)
{
try // Get default system look & feel
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (
UnsupportedLookAndFeelException |
ClassNotFoundException |
InstantiationException |
IllegalAccessException e)
{
e.printStackTrace();
}
new PaintFrame();
}
}
EDIT: Yes, all of the images are in the correct folder and are named correctly. No worries there.
public PaintFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true); // ***** telling Java to render the GUI
setSize(1150, 650);
setLocationRelativeTo(null);
setResizable(false);
setLayout(new BorderLayout());
setTitle("Paint 2.0");
addComponents(); // Add everything to the JFrame **after** rendering it! **
}
Don't call setVisible(true) until after adding all components to the GUI. Otherwise there's no guarantee that components added after calling setVisible(true) will ever be rendered.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
how can I get the buttons to appear on the line underneath the textarea?
//Imports
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
public class ProfessorPhysInstall {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
//Variables
final JFrame mainframe = new JFrame();
mainframe.setSize(500, 435);
final JPanel cards = new JPanel(new CardLayout());
final CardLayout cl = (CardLayout)(cards.getLayout());
mainframe.setTitle("Future Retro Gaming Launcher");
//Screen1
JPanel screen1 = new JPanel();
JTextPane TextPaneScreen1 = new JTextPane();
TextPaneScreen1.setEditable(false);
TextPaneScreen1.setBackground(new java.awt.Color(240, 240, 240));
TextPaneScreen1.setText("Welcome to the install wizard for Professor Phys!\n\nPlease agree to the following terms and click the next button to continue.");
TextPaneScreen1.setSize(358, 48);
TextPaneScreen1.setLocation(0, 0);
TextPaneScreen1.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black),BorderFactory.createEmptyBorder(5, 5, 5, 5)));
TextPaneScreen1.setMargin(new Insets(4,4,4,4));
screen1.add(TextPaneScreen1);
JTextArea TextAreaScreen1 = new JTextArea();
JScrollPane sbrText = new JScrollPane(TextAreaScreen1);
TextAreaScreen1.setRows(15);
TextAreaScreen1.setColumns(40);
TextAreaScreen1.setEditable(false);
TextAreaScreen1.setText("Lots of text");
TextAreaScreen1.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black),BorderFactory.createEmptyBorder(5, 5, 5, 5)));
TextAreaScreen1.setMargin(new Insets(4,4,4,4));
screen1.add(sbrText);
final JCheckBox Acceptance = new JCheckBox();
Acceptance.setText("I Accept The EULA Agreenment.");
screen1.add(Acceptance);
final JButton NextScreen1 = new JButton();
NextScreen1.setText("Next");
NextScreen1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if(Acceptance.isSelected())
cl.next(cards);
}
});
screen1.add(NextScreen1);
JButton CancelScreen1 = new JButton();
CancelScreen1.setText("Cancel");
CancelScreen1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
});
screen1.add(CancelScreen1);
cards.add(screen1);
//Screen2
JPanel screen2 = new JPanel();
JTextPane TextPaneScreen2 = new JTextPane();
TextPaneScreen2.setEditable(false);
TextPaneScreen2.setBackground(new java.awt.Color(240, 240, 240));
TextPaneScreen2.setText("Please select the Future Retro Gaming Launcher.");
TextPaneScreen2.setSize(358, 48);
TextPaneScreen2.setLocation(0, 0);
TextPaneScreen2.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black),BorderFactory.createEmptyBorder(5, 5, 5, 5)));
TextPaneScreen2.setMargin(new Insets(4,4,4,4));
screen2.add(TextPaneScreen2);
final JButton BackScreen2 = new JButton();
BackScreen2.setText("Back");
BackScreen2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if(Acceptance.isSelected())
cl.previous(cards);
}
});
screen2.add(BackScreen2);
final JButton NextScreen2 = new JButton();
NextScreen2.setText("Next");
NextScreen2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if(Acceptance.isSelected())
cl.next(cards);
}
});
screen2.add(NextScreen2);
JButton CancelScreen2 = new JButton();
CancelScreen2.setText("Cancel");
CancelScreen2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
});
screen2.add(CancelScreen2);
cards.add(screen2);
mainframe.add(cards);
mainframe.setVisible(true);
}
}
This is what it looks like
The default layout manager for JPanel is FlowLayout. As the name suggests, it simply flows the components one after the other.
You will need to try a different layout manager, something like GridBagLayout will do what you want, but it is a complex layout. You may be better of trying to use compound layouts to achieve the same effect.
That is, break the UI down into small chunks and apply different layout managers for each group.
Check out...
A Visual Guide to Layout Managers
Using Layout Managers
You will also benifit from reading...
Initial Threads
Code Conventions for the Java Programming Language
Ps...
You may also want to consider breaking each screen up into it's own class, the code as it stands is very hard to read and understands - IMHO
Use an appropriate LayoutManager
You've added all the components to screen2 which has a FlowLayout by default. There are many different ways to achieve what you're after.
More reading: Using Layout Managers
The usual way is to combine layouts for the look needed. E.G.
import java.awt.*;
import javax.swing.*;
public class ProfessorPhysInstall {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
//Variables
final JFrame mainframe = new JFrame();
mainframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
mainframe.setSize(500, 435);
final JPanel cards = new JPanel(new BorderLayout());
mainframe.setTitle("Future Retro Gaming Launcher");
//Screen2
JPanel screen2 = new JPanel();
JTextPane TextPaneScreen2 = new JTextPane();
TextPaneScreen2.setText("Please select the Future Retro Gaming Launcher.");
// set the preferred size, rather than the size!
//TextPaneScreen2.setSize(358, 48);
TextPaneScreen2.setPreferredSize(new Dimension(358, 48));
TextPaneScreen2.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.black),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
TextPaneScreen2.setMargin(new Insets(4,4,4,4));
screen2.add(TextPaneScreen2);
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER, 5,5));
final JButton BackScreen2 = new JButton();
BackScreen2.setText("Back");
buttons.add(BackScreen2);
final JButton NextScreen2 = new JButton("Next");
buttons.add(NextScreen2);
JButton CancelScreen2 = new JButton("Cancel");
buttons.add(CancelScreen2);
cards.add(screen2, BorderLayout.PAGE_START);
cards.add(buttons, BorderLayout.PAGE_END);
mainframe.add(cards);
mainframe.pack();
mainframe.setVisible(true);
}
}
Tips
Please learn common Java naming conventions (specifically the case used for the names) for class, method & attribute names & use them consistently.
For better help sooner, post an SSCCE.
Don't set the size of top level containers. Instead layout the content & call pack().
See the Nested Layout Example for ideas about how to combine layouts to create the required layout.
Also heed the advice already offered on the other two answers.
I am creating a program which has three jpanels: one container, and inside the container is two jpanels, one that is going to hold buttons and one which will hold the content. Ive got them both showing so far and its looking good, the only problem i I was hoping to add some space or a border between or the two (or around the button menu if possible) however since both internal panels are set to null layouts and the external layout is set to a border layout I cannot seem to add a border between the two internal ones. Here is my code so far:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class internal_test extends JFrame {
int height = 480;
int width = 640;
public internal_test() {
initUI();
}
private void initUI() {
JPanel container = new JPanel();
container.setLayout(new BorderLayout());
container.setBackground(Color.black);
JPanel buttonMenu = new JPanel();
buttonMenu.setLayout(null);
buttonMenu.setBackground(Color.DARK_GRAY);
buttonMenu.setPreferredSize(new Dimension(150, height));
JPanel dragFrame = new JPanel();
dragFrame.setLayout(null);
dragFrame.setPreferredSize(new Dimension(200, 100));
dragFrame.setSize(new Dimension(490, height));
dragFrame.setBackground(Color.gray);
container.add(buttonMenu, BorderLayout.WEST);
container.add(dragFrame, BorderLayout.CENTER);
// container.setBorder(new EmptyBorder(new Insets(10, 10, 10, 10)));
add(container);
pack();
setTitle("internal_test V0.1");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(width, height);
setLocationRelativeTo(null);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
internal_test c = new internal_test();
c.setVisible(true);
}
});
}
}
The dragFrame is going to be a DragLayout since that layout does what I need it to, but the button menu could technically be any layout, as long as it would allow me to place buttons/other items in a list with a label next to each.
Any help is greatly appreciated.
I would use the BoxLayout and for the spacing use
panel.add(Box.createRigidArea(new Dimension(x, y)));
Here are some decent examples.
I Suggest GridBagLayout
beacause it is more easy to intent spaces between the components
This should help you add the type of border you want:
http://docs.oracle.com/javase/tutorial/uiswing/components/border.html
You can start with a red line border like this:
buttonMenu.setBorder(BorderFactory.createLineBorder(Color.red));