Essentially, I am trying to add a home screen with 4 buttons, 3 difficulty buttons and a play button. I add the buttons to a JPanel and add the JPanel with a BoxLayout of Center. Why does the buttons still go all the way off to the right? Setting the icon for a JLabel on and adding it to the home screen JPanel is a possible mess up the flow of components? I want the difficulty buttons to be on top of the of the gif with the Play button at the bottom. Thanks for your help.
//container
snake = new JFrame();
snake.setLayout(new BorderLayout());
//home screen panel
homeScreen = new JPanel();
homeScreen.setLayout(new BoxLayout(homeScreen, BoxLayout.X_AXIS));
homeScreen.setPreferredSize(new Dimension(320, 320));
JLabel bg = new JLabel();
ImageIcon icon = new ImageIcon("HomeBG.gif");
icon.getImage().flush();
bg.setIcon(icon);
homeScreen.add(bg);
easy = new JButton("Easy");
medium = new JButton("Medium");
hard = new JButton("Hard");
play = new JButton("Play");
//button listeners code here
homeScreen.add(easy);
homeScreen.add(medium);
homeScreen.add(hard);
homeScreen.add(play);
snake.add(homeScreen, BorderLayout.CENTER);
snake.setTitle("Snake Game");
snake.pack();
snake.setVisible(true);
snake.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
You need to change your code as shown below.
snake = new JFrame();
snake.setLayout(new BorderLayout());
//home screen panel
homeScreen = new JPanel(new BorderLayout());
//homeScreen.setLayout(new BoxLayout(homeScreen, BoxLayout.X_AXIS));
homeScreen.setPreferredSize(new Dimension(320, 320)); // probably you need to remove this line!
JLabel bg = new JLabel();
ImageIcon icon = new ImageIcon("HomeBG.gif");
icon.getImage().flush();
bg.setIcon(icon);
homeScreen.add(bg);
easy = new JButton("Easy");
medium = new JButton("Medium");
hard = new JButton("Hard");
play = new JButton("Play");
//button listeners code here
JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
buttonsPanel.add(easy);
buttonsPanel.add(medium);
buttonsPanel.add(hard);
buttonsPanel.add(play);
homeScreen.add(buttonsPanel, BorderLayout.NORTH);
snake.add(homeScreen, BorderLayout.CENTER);
snake.setTitle("Snake Game");
snake.pack();
snake.setVisible(true);
snake.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
I would use a compound layout for this. Put the level buttons in a (panel in a) FlowLayout. Put the play button in a 2nd FlowLayout. Add those panels to the PAGE_START and PAGE_END of a BorderLayout. Add a label containing the GIF to the CENTER of the same border layout.
BTW - the level buttons should be radio buttons (in a button group - BNI).
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class LayoutManagersWithIcon {
private JComponent ui = null;
LayoutManagersWithIcon() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new BorderLayout(4,4));
ui.setBorder(new EmptyBorder(4,4,4,4));
JPanel levelPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
ui.add(levelPanel, BorderLayout.PAGE_START);
levelPanel.add(new JRadioButton("Easy"));
levelPanel.add(new JRadioButton("Medium"));
levelPanel.add(new JRadioButton("Hard"));
JPanel startPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
ui.add(startPanel, BorderLayout.PAGE_END);
startPanel.add(new JButton("Play"));
JLabel label = new JLabel(new ImageIcon(
new BufferedImage(400, 100, BufferedImage.TYPE_INT_RGB)));
ui.add(label);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
LayoutManagersWithIcon o = new LayoutManagersWithIcon();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
Related
I have a card layout where I switch panels with a button. However, the code (switching panels) works only when lines:
JScrollPane scrPane = new JScrollPane(card1);
frame.add(scrPane);
are removed. In other case, clicking button achieves nothing. Is there an option to keep the scrolling (I need this, since the main application will have a lot of wrapped text) without disabling an option to switch cards?
package com.code;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.event.*;
public class Card {
public static void main(String[] args) {
JFrame frame = new JFrame("App");
frame.setVisible(true);
frame.setSize(1200, 800);//Give it a size
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel mainPanel = new JPanel(new CardLayout());
frame.add(mainPanel);
JPanel menu = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel card1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel card2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
mainPanel.add(menu, "menu");
mainPanel.add(card1, "card1");
mainPanel.add(card2, "card2");
JLabel l1 = new JLabel("label 1");
JLabel l2 = new JLabel("label 2");
card1.add(l1);
card2.add(l2);
JButton click = new JButton("Click!");
menu.add(click);
JScrollPane scrPane = new JScrollPane(card1);
frame.add(scrPane);
click.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout cardLayout = (CardLayout) mainPanel.getLayout();
cardLayout.show(mainPanel, "card1");
}
});
}
}
A JFrame (its content pane) uses BorderLayout by default. That means you can have only 1 component at BorderLayout.CENTER. When you frame.add(component) the default constraints is BorderLayout.CENTER.
Now, you frame.add(mainPanel); and then frame.add(scrPane);. So main panel is removed, since scrPane is being added after it.
Doing JScrollPane scrPane = new JScrollPane(card1); it means you add a scrollpane to card1, and not in content pane. I guess that you want it to the content pane (the whole frame). So the fix is to delete frame.add(mainPanel); and do the following:
JScrollPane scrPane = new JScrollPane(mainPanel);
frame.add(scrPane);
Now, the main panel is added to scrPane and scrPane is added to the frame.
However, your GUI will be empty after that, because you frame.setVisible(true); before you are finished adding components to it. Take a look at Why shouldn't I call setVisible(true) before adding components?
Eventually, full code is:
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("App");
frame.setSize(1200, 800);//Give it a size
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel mainPanel = new JPanel(new CardLayout());
JPanel menu = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel card1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel card2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
mainPanel.add(menu, "menu");
mainPanel.add(card1, "card1");
mainPanel.add(card2, "card2");
JLabel l1 = new JLabel("label 1");
JLabel l2 = new JLabel("label 2");
card1.add(l1);
card2.add(l2);
JButton click = new JButton("Click!");
menu.add(click);
JScrollPane scrPane = new JScrollPane(mainPanel);
frame.add(scrPane);
click.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout cardLayout = (CardLayout) mainPanel.getLayout();
cardLayout.show(mainPanel, "card1");
}
});
frame.setVisible(true);
});
}
Some good links I suggest you to read are the Initial Threads and What does .pack() do?
I need to make a scrolling background for this platformer. It needs to scroll a 2400x500 image while the frame size is about 1440x900. If it could just gradually change over time that would be great. This is my code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import javax.swing.*;
public class Main extends JFrame {
public Main() {
//Creates Title Image
JLabel title = new JLabel(" ");
ImageIcon tl = new ImageIcon("title.gif");
title.setIcon(tl);
//Creates Start Image
final JButton start = new JButton("");
ImageIcon st = new ImageIcon("start.gif");
start.setIcon(st);
//Creates Options Image
JButton options = new JButton("");
ImageIcon opt = new ImageIcon("options.gif");
options.setIcon(opt);
options.setBackground(Color.BLACK);
//Creates label for level 0 background image
JLabel background = new JLabel(" ");
ImageIcon back = new ImageIcon("level0.gif");
background.setIcon(back);
//Creates a panel for level 0
final JPanel p5 = new JPanel();
p5.setLayout (new BorderLayout(1, 1));
p5.add(background);
//Create first frame for "Start" button
final JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(1, 1));
p1.add(start, BorderLayout.CENTER);
//Create second panel for title label
final JPanel p2 = new JPanel(new BorderLayout());
p2.setLayout(new GridLayout(1, 3));
p2.add(title, BorderLayout.WEST);
//Create third panel for "Options" button
final JPanel p3 = new JPanel(new BorderLayout());
p3.setLayout(new GridLayout(1, 1));
p3.add(options, BorderLayout.SOUTH);
//Creates fourth panel to organize all other primary
final JPanel p4 = new JPanel(new BorderLayout());
p4.setLayout(new GridLayout(1, 3));
p4.add(p1, BorderLayout.WEST);
p4.add(p2, BorderLayout.CENTER);
p4.add(p3, BorderLayout.EAST);
//When button is clicked, it changes the level
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(start.isEnabled()) {
remove(p4);
add(p5, BorderLayout.CENTER);
invalidate();
validate();
}
else {
return;
}
}
});
//Adds fourth panel to frame
add(p4, BorderLayout.CENTER);
}
public static void main(String args[]) {
Main frame = new Main();
//Finds screen size of monitor
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//Creates the frame
frame.setTitle("Cockadoodle Duty: Awakening");
frame.setSize(screenSize);
frame.setLocale(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
String background = "#000000";
frame.setBackground(Color.decode(background));
}
}
Add the label containing the icon to a scroll panel
Use a Swing Timer to schedule the scrolling
When the Timer fires you can scroll background.
The scrolling code might be something like:
JViewport viewport = scrollPane.getViewport();
Point position = viewport.getViewPosition();
position.x += 2;
viewport.setViiewPosition( position );
Its pretty basic UI, but I cannot setup the JCheckBox buttons so that they are placed immediately after one another (vertically) without any spacing. How would I reduce the spacing seen below?
JPanel debugDrawPanel = new JPanel(new GridLayout(0,1));
JPanel eastPanel = new JPanel(new GridLayout(1,0));
JTabbedPane tab = new JTabbedPane();
click = new ClickPanel(this);
setSettings(new Settings());
for (Setting setting: getSettings().getAll()){
JCheckBox checkBox = new JCheckBox(setting.name);
checkBox.setName(setting.name);
checkBox.addItemListener(new CheckBoxItemListener(this));
debugDrawPanel.add(checkBox);
}
tab.addTab("Object Parameters", click);
tab.addTab("Debug Draw", debugDrawPanel);
It appears that the minimum vertical size is being set by the content of another tab. One way to get around that is to put the GridLayout in the PAGE_START of a BorderLayout before putting the panel with border layout into the tabbed pane.
The panel with GridLayout has an orange BG.
The panel with BorderLayout has a yellow BG.
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class TopAlignedComponents {
private JComponent ui = null;
TopAlignedComponents() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new BorderLayout(4,4));
ui.setBorder(new EmptyBorder(4,4,4,4));
JTabbedPane tb = new JTabbedPane();
ui.add(tb);
Image spacer = new BufferedImage(300, 100, BufferedImage.TYPE_INT_RGB);
tb.addTab("Spacer", new JLabel(new ImageIcon(spacer)));
String[] labels = {"Shapes", "Joints", "AABBs"};
JPanel checkPanel = new JPanel(new GridLayout(0, 1, 4, 4));
checkPanel.setBackground(Color.ORANGE);
for (String label : labels) {
checkPanel.add(new JCheckBox(label));
}
JPanel checkConstrain = new JPanel(new BorderLayout());
checkConstrain.setBackground(Color.YELLOW);
checkConstrain.add(checkPanel, BorderLayout.PAGE_START);
tb.addTab("Check", checkConstrain);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
TopAlignedComponents o = new TopAlignedComponents();
JFrame f = new JFrame("Top Aligned Components");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
If i remember correctly, its because of your layout!
GridLayout divides your windowsize into equal parts, so i think you should either unset your windows size and use pack() or you could switch to a different layout.
( I assume your window's size is or minimum-size is set somewhere )
I have a JPanel which is in a box layout but I am unsure how to align the JPanel to center of the window (and stay centered even if window is resized) I've tried looking for a solution but all questions seem over complicated compared to what it is that I'm looking for.
import java.awt.*;
import javax.swing.*;
public class Stacker extends JFrame {
public Stacker() {
super("Stacker");
setSize(430, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create top panel
JPanel commandPane = new JPanel();
BoxLayout vertical = new BoxLayout(commandPane,
BoxLayout.Y_AXIS);
commandPane.setLayout(vertical);
JButton subscribe = new JButton("Subscribe");
JButton unsubscribe = new JButton("Unsubscribe");
JButton refresh = new JButton("Refresh");
JButton save = new JButton("Save");
commandPane.add(subscribe);
commandPane.add(unsubscribe);
commandPane.add(refresh);
commandPane.add(save);
JMenuItem j1 = new JMenuItem("File");
JMenuItem j2 = new JMenuItem("Open");
JMenuItem j3 = new JMenuItem("Close");
JMenuBar menubar = new JMenuBar();
JMenu menu = new JMenu("Feeds");
menu.add(j1);
menu.add(j2);
menu.add(j3);
menubar.add(menu);
setJMenuBar(menubar);
// create bottom panel
/*JPanel textPane = new JPanel();
JTextArea text = new JTextArea(4, 70);
JScrollPane scrollPane = new JScrollPane(text);
// put them together
FlowLayout flow = new FlowLayout();
setLayout(flow);
add(commandPane);
add(scrollPane); */
setJMenuBar(menubar);
add(commandPane);
setVisible(true);
}
public static void main(String[] arguments) {
Stacker st = new Stacker();
}
}
You say you're using a BoxLayout, but is the JPanel with the BoxLayout the JPanel you want to center, or does it contain the JPanel you want to center?
If it contains the JPanel you want to center, then you can add a glue on either side of the JPanel to be centered. If it is the JPanel you want to center, then you can use GridBagLayout or BoxLayout to achieve the effect you're talking about.
Googling something like "Java center component" will give you a ton of results.
for this idea (still not clear from your description) use GridBagLayout without set for GridBagConstraints
.
.
.
import java.awt.*;
import javax.swing.*;
public class CenteredJPanel {
private JFrame frame = new JFrame("Test");
private JPanel panel = new JPanel();
private JButton subscribe = new JButton("Subscribe");
private JButton unsubscribe = new JButton("Unsubscribe");
private JButton refresh = new JButton("Refresh");
private JButton save = new JButton("Save");
public CenteredJPanel() {
panel.setLayout(new GridBagLayout());
panel.add(subscribe);
panel.add(unsubscribe);
panel.add(refresh);
panel.add(save);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
CenteredJPanel centeredJLabel = new CenteredJPanel();
}
});
}
}
I really didn't now how to form the question i have a gridlayout with 4 buttons. When the user press Add module i want under the buttons a form instead of a new windows if this is possible.
frame = new JFrame("ModuleViewer");
makeMenu(frame);
Container contentPane = frame.getContentPane();
// Specify the layout manager with nice spacing
contentPane.setLayout(new GridLayout(0, 2));
addModule = new JButton("Toevoegen Module");
contentPane.add(addModule);
overview = new JButton("Overzicht Modules");
contentPane.add(overview);
addSchoolweeks = new JButton("Aapassen schoolweken");
contentPane.add(addSchoolweeks);
weekheavy = new JButton("Weekbelasting");
contentPane.add(weekheavy);
frame.pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2 - frame.getWidth()/2, d.height/2 - frame.getHeight()/2);
frame.setVisible(true);
I know that i first need to add een action method for the buttons i know how to do that so that isn't important. I only want to know how i could create a layout under the buttons so when a user clicks the layout will be draw.
Each panel can only have one layout, but you can use multiple panels for the desired effect: a top panel using GridLayout to hold your buttons, and a bottom panel using CardLayout to hold multiple other panels, one for each button click. Each of these panels can use whatever layout you want, depending on its contents.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CardLayoutDemo implements Runnable
{
final static String CARD1 = "Red";
final static String CARD2 = "Green";
final static String CARD3 = "Blue";
JPanel cards;
CardLayout cardLayout;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new CardLayoutDemo());
}
public void run()
{
JButton btnRed = createButton("Red");
JButton btnGreen = createButton("Green");
JButton btnBlue = createButton("Blue");
JPanel buttons = new JPanel(new GridLayout(1,3));
buttons.add(btnRed);
buttons.add(btnGreen);
buttons.add(btnBlue);
JPanel card1 = new JPanel();
card1.setBackground(Color.RED);
JPanel card2 = new JPanel();
card2.setBackground(Color.GREEN);
JPanel card3 = new JPanel();
card3.setBackground(Color.BLUE);
cardLayout = new CardLayout();
cards = new JPanel(cardLayout);
cards.add(card1, CARD1);
cards.add(card2, CARD2);
cards.add(card3, CARD3);
JFrame f = new JFrame("CardLayout Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(buttons, BorderLayout.NORTH);
f.add(cards, BorderLayout.CENTER);
f.setSize(300, 200);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JButton createButton(final String name)
{
JButton button = new JButton(name);
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
cardLayout.show(cards, name);
}
});
return button;
}
}