I have a simple GUI program I'm trying to get to work. When the user presses the bottom button I'm trying to get some shapes to paint. When I get rid of the if(buttonClicked) in paint() everything shows up fine but paint() seems to be auto-executed and the shapes appear without any button click. When I add surround the paint() body with if(buttonClicked), regardless of how the ButtonHandler class handles it, the rest of my components do not even show up in the frame. I have no idea why this is happening. Test the code with and without the if logic in paint() and you will see what's going on.
public class GUI extends JFrame {
//declare components
Container container;
JPanel centerPanel, northPanel, southPanel, eastPanel, westPanel, mouseClickPanel;
JLabel topLabel;
JTextArea textArea;
JButton buttonA, buttonB, drawButton;
boolean buttonClicked;
public GUI(String title) {
super(title); // invoke JFrame Constructor
container = getContentPane();
container.setLayout(new BorderLayout());
centerPanel = new JPanel();
centerPanel.setBackground(Color.CYAN);
northPanel = new JPanel();
northPanel.setBackground(Color.GREEN);
southPanel = new JPanel();
southPanel.setBackground(Color.MAGENTA);
eastPanel = new JPanel();
eastPanel.setBackground(Color.ORANGE);
westPanel = new JPanel();
westPanel.setBackground(Color.YELLOW);
mouseClickPanel = new JPanel();
mouseClickPanel.setBackground(Color.GRAY);
mouseClickPanel.setPreferredSize(new Dimension(400, 400));
topLabel = new JLabel("Press either button to make something happen");
topLabel.setFont(new Font("Calibri", Font.PLAIN, 16));
topLabel.setHorizontalAlignment(JLabel.CENTER);
textArea = new JTextArea(3, 20);
textArea.setEditable(false);
buttonA = new JButton("Press Here");
buttonB = new JButton("Press Here");
drawButton = new JButton("Press here");
container.add(centerPanel, BorderLayout.CENTER);
container.add(northPanel, BorderLayout.NORTH);
container.add(southPanel, BorderLayout.SOUTH);
container.add(eastPanel, BorderLayout.EAST);
container.add(westPanel, BorderLayout.WEST);
northPanel.add(topLabel, BorderLayout.NORTH);
centerPanel.add(buttonA);
centerPanel.add(textArea);
centerPanel.add(buttonB);
centerPanel.add(mouseClickPanel);
centerPanel.add(drawButton);
buttonClicked = false;
ButtonHandler buttonHandler = new ButtonHandler(buttonA, drawButton, textArea, buttonClicked);
buttonA.addActionListener(buttonHandler); // add actionListeners to buttonA and B
buttonB.addActionListener(buttonHandler);
drawButton.addActionListener(buttonHandler);
setSize(525, 600);
setVisible(true);
}
public void paint(Graphics g) {
if (buttonClicked) {
super.paint(g);
g.setColor(Color.RED);
g.fillOval(150, 150, 50, 50);
g.draw3DRect(200, 200, 50, 50, true);
}
}
}
Handler class:
public class ButtonHandler extends JFrame implements ActionListener {
private JButton buttonA, drawButton;
private JTextArea textArea;
boolean buttonClicked;
public ButtonHandler(JButton buttonA, JButton drawButton, JTextArea textArea, boolean buttonClicked) {
this.buttonA = buttonA;
this.textArea = textArea;
this.drawButton = drawButton;
this.buttonClicked = buttonClicked;
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == buttonA) {
textArea.setText(" <- You pressed left button");
}
else if (e.getSource() == drawButton) {
textArea.setText("You pressed button to draw rectangle");
buttonClicked = true;
repaint();
}
else {
textArea.setText("You pressed right button ->");
}
}
}
Take super.paint(g); out of the if statement. Have it as the first line. Otherwise, no painting at all (including the JPanel internals such as background) will happen unless the button is clicked.
Related
I currently have GridLayout(3,0) and I want to add some buttons. However, nothing shows up when I run my program.
Here is the code (the class extends JFrame):
public void initializeGraphics() {
setLayout(new BorderLayout());
setMinimumSize(new Dimension(1900, 1000));
getContentPane().setLayout(null);
setVisible(true);
createMenu();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void createMenu() {
JPanel menuArea = new JPanel();
menuArea.setLayout(new GridLayout(3,0));
menuArea.setBounds(40,40,740,870);
JButton button1 = new JButton("test1");
JButton button2 = new JButton("test2");
JButton button3 = new JButton("test3");
menuArea.add(button1);
menuArea.add(button2);
menuArea.add(button3);
add(menuArea);
}
You need to create your UI component before setting visible attributes.
edit your code as:
createMenu();
setVisible(true);
I am having some issues with my Swing GUI.
It currently looks like this:
But I would like to move a couple things around.
Firstly I want the buttons underneath the keyboard
I want to add a text field on top of the keyboard with the submit button on the right hand side.
How can I accomplish this? I've tried to create a GridLayout and slot things by row,column coordinate but it doesn't seem to work.
private class Display extends JPanel {
Display() {
setPreferredSize(new Dimension(620, 420));
setBackground(new Color(250, 230, 180));
setFont(new Font("Serif", Font.BOLD, 20));
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D) g).setStroke(new BasicStroke(3));
if (message != null) {
g.setColor(Color.RED);
g.drawString(message, 30, 40);
g.drawString("00:00", 30, 410);
}
}
}
private void createWindow() {
setJMenuBar(menuBarCreator());
// The ActionListener that will respond to button clicks.
ButtonHandler buttonHandler = new ButtonHandler();
// Create the subpanels and add them to the main panel.
display = new Display();
setLayout(new BorderLayout(3, 3));
add(display, BorderLayout.CENTER);
JPanel bottom = new JPanel();
bottom.setLayout(new GridLayout(1,1));
add(bottom, BorderLayout.NORTH);
// Add keyboard
JPanel keyboard = new JPanel();
JPanel keyboardHolder = new JPanel();
keyboard.setLayout(new GridLayout(2, 13));
keyboardHolder.setLayout(new GridLayout(1, 2));
for (char alphabet = 'a'; alphabet <= 'z'; alphabet++) {
JButton button = new JButton(String.valueOf(alphabet));
button.addActionListener(buttonHandler);
keyboard.add(button);
alphabetButtons.add(button);
}
keyboardHolder.add(keyboard, 0,0);
add(keyboardHolder, BorderLayout.SOUTH);
// Create three buttons, register the ActionListener to respond to clicks on the
// buttons, and add them to the bottom panel.
JButton submitButton = new JButton("Submit");
submitButton.addActionListener(buttonHandler);
keyboard.add(submitButton);
JButton startButton = new JButton(GuiText.START.toString());
startButton.addActionListener(buttonHandler);
bottom.add(startButton);
JButton nextButton = new JButton(GuiText.NEXT.toString());
nextButton.addActionListener(buttonHandler);
bottom.add(nextButton);
JButton skipButton = new JButton(GuiText.SKIP.toString());
skipButton.addActionListener(buttonHandler);
bottom.add(skipButton);
JButton quit = new JButton(GuiText.QUIT.toString());
quit.addActionListener(buttonHandler);
bottom.add(quit);
setBackground(new Color(100, 0, 0));
nextButton.setEnabled(false);
skipButton.setEnabled(false);
}
Below is a concrete example of what camickr wrote in his comment to the original question. Note that this is not the only possibility. There are many layout managers. I recommend visiting Laying Out Components Within a Container
The purpose of the code is only to show you how to achieve your desired layout.
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class GuesGame implements Runnable {
private JFrame frame;
public void run() {
showGui();
}
private JPanel createBottomPanel() {
JPanel bottomPanel = new JPanel(new GridLayout(3, 1));
bottomPanel.add(createSubmitPanel());
bottomPanel.add(createKeyboardPanel());
bottomPanel.add(createButtonsPanel());
return bottomPanel;
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
JButton startButton = new JButton("Start");
buttonsPanel.add(startButton);
JButton nextButton = new JButton("Next");
buttonsPanel.add(nextButton);
JButton skipButton = new JButton("Skip");
buttonsPanel.add(skipButton);
JButton quitButton = new JButton("Quit");
buttonsPanel.add(quitButton);
return buttonsPanel;
}
private JPanel createKeyboardPanel() {
JPanel keyboardPanel = new JPanel(new GridLayout(2, 13));
for (char c = 'a'; c <= 'z'; c++) {
JButton button = new JButton(String.valueOf(c));
keyboardPanel.add(button);
}
return keyboardPanel;
}
private JPanel createSubmitPanel() {
JPanel submitPanel = new JPanel();
JTextField txtFld = new JTextField(20);
submitPanel.add(txtFld);
JButton submitButton = new JButton("Submit");
submitPanel.add(submitButton);
return submitPanel;
}
private void showGui() {
frame = new JFrame("Guess Game");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(new Display(), BorderLayout.CENTER);
frame.add(createBottomPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new GuesGame());
}
}
class Display extends JPanel {
private String message;
Display() {
message = "Starting game";
setPreferredSize(new Dimension(620, 420));
setBackground(new Color(250, 230, 180));
setFont(new Font("Serif", Font.BOLD, 20));
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
((Graphics2D) g).setStroke(new BasicStroke(3));
if (message != null) {
g.setColor(Color.RED);
g.drawString(message, 30, 40);
g.drawString("00:00", 30, 410);
}
}
}
You want three "rows" below the Display panel as follows
Text field and "submit" button.
Keyboard
Other buttons.
Hence the "bottom" panel contains three panels laid out one above the other.
The first panel is the text field and "submit" panel.
Underneath that is the "keyboard".
And underneath the keyboard are the other buttons.
Note that the default layout manager for JPanel is java.awt.FlowLayout and this layout manager is suitable for the panel containing the "submit" button and also suitable for the panel containing the other buttons.
Here is a screen capture of the running app.
I would like to add a JPanel from another class to a JPanel:
class FirstPanel extends JPanel
{
private JButton button;
FirstPanel()
{
setLayout(null);
setVisible(true);
button = new JButton();
button.setBounds(x, y, width, height);
button.setFocusPainted(false);
button.setIcon(new ImageIcon(SecondPanel.class.getResource(filePath)));
button.setBackground(bgColor);
button.setForeground(Color.white);
button.setVisible(true);
Border emptyBorder = BorderFactory.createEmptyBorder();
button.setBorder(emptyBorder);
add(button);
ButtonActionHandler buttonActionHandler = new ButtonActionHandler();
}
public class ButtonActionHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
setVisible(true);
add(new SecondJPanel());
new SecondJPanel().setVisible(true);
}
} }
And this is my Second JPanel:
class SecondPanel extends JPanel
{
private JButton button;
private JLabel titleLabel;
SecondPanel()
{
setLayout(null);
setVisible(true);
button = new JButton();
button.setBounds(100, 200, 100, 200);
button.setFocusPainted(false);
button.setIcon(new ImageIcon(SecondPanel.class.getResource(filePath)));
button.setBackground(bgColor);
button.setForeground(Color.white);
button.setVisible(true);
Border emptyBorder = BorderFactory.createEmptyBorder();
button.setBorder(emptyBorder);
add(button);
}
}
The Launching of the First Panel through a JFrame (from another class) works, however the adding of the second JPanel to the first one doesn't.
Any help is really appreciated
I'm sorry, but you don't seem to be understanding what I am telling you.
Composition is your friend.
I would do it like this:
public class JPanel1 extends JPanel {
private JButton button;
public JPanel1(ActionListener buttonListener) {
this.button = new Button("Push me");
this.button.addActionListener(buttonListener);
// do what's needed to add the button to the display.
}
}
public class JPanel2 extends JPanel {
private JButton button;
public JPanel2(ActionListener buttonListener) {
this.button = new Button("Push me");
this.button.addActionListener(buttonListener);
// do what's needed to add the button to the display.
}
}
public class TwoPanelFrame extends JFrame {
public TwoPanelFrame(JPanel p1, JPanel p2) {
// add the two panels to your frame and display.
}
}
I am very new to GUI and am wondering how to change the BG color of a JButton when that respective button is pressed. I am not sure how to even properly structure GUI for this my first time.
public static void createWindow(int x)
{
JFrame frame = new JFrame("WINDOW");
frame.setSize(40*x, 40*x);
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
for(int i = 0; i < x * x; i++)
{
JButton button = new JButton();
button.setPreferredSize(new Dimension(40, 40));
panel.add(button);
button.addActionListener(new Action());
}
frame.add(panel);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
static class Action implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//changes color of button
}
}
Your ActionListener might look something like:
public void actionPerformed(ActionEvent e)
{
JButton button = (JButton)e.getSource();
button.setBackground( Color.RED );
}
And you only need one ActionListener because the code is generic since the button clicked will come from the event.
Also, Don't use Action for the Class name. There is an interface by that name so it gets confusing. Use a more descriptive name.
I have a JLabel with an ImageIcon that isn't showing.
public class Lockscreen extends JFrame {
JPanel layer;
JButton signin;
ImageIcon heartlock;
String heartlockpath;
JLabel heartlockdisplay;
String arrowpath;
public Lockscreen(){
super("Startseite");
setSize(700, 400);
setLocation(100, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
arrowpath = "C:\\Users\\saydanan\\Pictures\\FürMyDiary\\Right_Arrow.png";
signin = new JButton();
signin.setSize(19, 12);
signin.setIcon(new ImageIcon(arrowpath));
signin.setLocation(250, 500);
heartlockpath = "C:\\Users\\saydananPicturesFürMyDiary\\082326-green-jelly-icon-business-lock-heart.png";
heartlock = new ImageIcon(heartlockpath);
heartlockdisplay = new JLabel();
heartlockdisplay.setIcon(heartlock);
heartlockdisplay.setLocation(250, 250);
heartlockdisplay.setSize(heartlock.getIconWidth(), heartlock.getIconHeight());
heartlockdisplay.setVisible(true);
layer = new JPanel();
layer.setBackground(Color.black);
/*layer.setLayout(...);*/
addEverything(layer);
getContentPane().add(layer);
setVisible(true);
}
public void addEverything(JPanel panel){
panel.add(signin);
panel.add(heartlockdisplay);
panel.repaint();
}
}
You need to add it, and then set it to be visible.
As in:
panel.add(heartlockdisplay);
heartlockdisplay.setVisible(true);
panel.setVisible(true);