How to fix JButton Location - java

Previously I have asked a question about this program and I fixed it with you people. Now I have created new panel on the first panel which is containing the game of shapes. So I tried to set JButton on the new panel. But I cannot change the location of Jbuttons.
I am trying to set center of new panel.I have tried already FLowLayout(), BorderLayout() and setBounds(); Something is going wrong.
Previous questions; How to move JFrame shape
public class myshapestry extends JFrame implements ActionListener {
JFrame frame=new JFrame("Deneme");
Startthegame panelstart= new Startthegame();
Container l ;
JLabel statusbar = new JLabel("default");
static JButton start;
static JButton exit;
myshapestry() {
l=this.getContentPane();
this.setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.add(panelstart);
frame.add(statusbar, BorderLayout.SOUTH);
frame.setVisible(true);
frame.setSize(getPreferredSize());
start = new JButton("Start");
exit = new JButton("Exit");
panelstart.add(start);
panelstart.add(exit);
}
public Dimension getPreferredSize() {
return new Dimension(500,600);
}
public static void main (String args[]){
myshapestry tr=new myshapestry();
tr.setTitle("Game of Shapes");
}
public class Startthegame extends JPanel {
}
}

You're extending from JFrame, but creating a new instance of JFrame within the class and interacting with both, which is just confusing the issues. Start by getting rid of extends JFrame, you're not adding any new functionality to the class and it's just locking you into a single use case
static is not your friend and you should avoid using it where possible. In this case, you can move the buttons to the Startthegame. This is basic OO principle of isolation responsibility to units of work.
To get the buttons to center horizontally and vertically within the container, you can use a GridBagLayout
public class Startthegame extends JPanel {
private JButton start;
private JButton exit;
public Startthegame() {
setLayout(new GridBagLayout());
start = new JButton("Start");
exit = new JButton("Exit");
add(start);
add(exit);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 600);
}
}
You should also call setVisible AFTER you've established the basic UI, otherwise you could end up within components not been displayed
For example...
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MyShapesTry {
JFrame frame = new JFrame("Deneme");
Startthegame panelstart = new Startthegame();
Container l;
JLabel statusbar = new JLabel("default");
public MyShapesTry() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panelstart);
frame.add(statusbar, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
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();
}
MyShapesTry tr = new MyShapesTry();
}
});
}
}

Related

Is it possible to add a image in JFrame but the class is extended with JPanel?

Here is my code, i can run it in class extended with JFrame. But now i need to add this code to a class extended with JPanel. Is it possible to add this in JPanel class? If cannot how can i add an image in JPanel class?
JLabel img;
String url = "image/Screenshot(295).png";
void Car() {
frame=new JFrame("Malaysia Checker");
frame.getContentPane().setBackground(Color.white);
img = new JLabel();
ImageIcon icon = new ImageIcon(url);
img.setIcon(icon);
img.setBounds(200, 200, 200, 200);
add(img);
frame.setVisible(true);
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Simple answer is, yes, and you should. A JPanel is just a type of container, a JFrame is a specialised type of container, so many of the concepts are transferable.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
setBackground(Color.WHITE);
try {
// Warning, this is a blocking call and my slow down the launch/presentation of the view
BufferedImage background = ImageIO.read(new URL("https://upload.wikimedia.org/wikipedia/en/thumb/3/30/Java_programming_language_logo.svg/234px-Java_programming_language_logo.svg.png"));
JLabel label = new JLabel(new ImageIcon(background));
add(label);
} catch (IOException ex) {
ex.printStackTrace();
add(new JLabel("Could not load background image"));
}
}
}
}
Remember, in order to display any component, you need some kind of Window class, here I've just used a JFrame as the top level container
This kind of question would be better answer by reading through the Creating a GUI With JFC/Swing tutorials

Update JLabel text

I'm working on a simple GUI. On Button press i want to increase/decrease a variable and update the corresponding JLabel.
class JFrameSetUp
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JFrameSetUp extends JFrame implements ActionListener {
private int RecHeight = 0;
private int RecWidth = 0;
//Here Buttons
JButton HeightIncrease = new JButton("+");
JButton HeightDecrease = new JButton("-");
JLabel height = new JLabel(Integer.toString(RecHeight));
JLabel width = new JLabel(Integer.toString(RecWidth));
GridLayout gridLayout = new GridLayout(2, 4);
public JFrameSetUp(){
}
public void addComponentsToPane(final Container pane){
//Create GridPanel and set Layout
JPanel grid = new JPanel();
grid.setLayout(gridLayout);
//Create buttondrawPanel and set Layout
JPanel buttondraw = new JPanel();
buttondraw.setLayout(new GridLayout(2, 0));
//Adding Components to GridPanel
//Adding Layouts to pane
pane.add(grid, BorderLayout.NORTH);
pane.add(new JSeparator(), BorderLayout.CENTER);
pane.add(buttondraw, BorderLayout.SOUTH);
}
#Override
public void actionPerformed(ActionEvent e) {
//Setting up ActionListener to Buttons
if (e.getSource() == this.HeightDecrease) {
RecHeight -= 1;
height.setText(Integer.toString(RecHeight));
} else if (e.getSource() == this.HeightIncrease) {
RecHeight += 1;
height.setText(Integer.toString(RecHeight));
}
}
}
Class with MainMethod
import javax.swing.JFrame;
public class Program {
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrameSetUp frame = new JFrameSetUp();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
frame.addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
}
I'm aware, that's kind a newbish question. I think I'm wrong with my Code Structure. Any help is appreciated.
Thanks in advance.
You never register any ActionListeners to the buttons...
HeightIncrease.addActionListener(this);
HeightDecrease.addActionListener(this);
You also never add the buttons to the GUI
buttondraw.add(HeightIncrease);
buttondraw.add(HeightDecrease);
You also never add the labels to the GUI either...
grid.add(height);
grid.add(width);
I reworked the code, because your example was messing with my mind, hope you don't mind...
It's conceptually the same idea, just done slightly more efficently
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private int recHeight = 0;
private int recWidth = 0;
//Here Buttons
JButton heightIncrease = new JButton("+");
JButton heightDecrease = new JButton("-");
JLabel height = new JLabel(Integer.toString(recHeight));
JLabel width = new JLabel(Integer.toString(recWidth));
GridLayout gridLayout = new GridLayout(2, 4);
public TestPane() {
setLayout(new BorderLayout());
//Create GridPanel and set Layout
JPanel grid = new JPanel();
grid.setLayout(gridLayout);
grid.add(height);
grid.add(width);
//Create buttondrawPanel and set Layout
JPanel buttondraw = new JPanel();
buttondraw.setLayout(new GridLayout(2, 0));
heightIncrease.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
recHeight += 1;
height.setText(Integer.toString(recHeight));
}
});
heightDecrease.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
recHeight -= 1;
height.setText(Integer.toString(recHeight));
}
});
buttondraw.add(heightIncrease);
buttondraw.add(heightDecrease);
//Adding Components to GridPanel
//Adding Layouts to pane
add(grid, BorderLayout.NORTH);
add(new JSeparator(), BorderLayout.CENTER);
add(buttondraw, BorderLayout.SOUTH);
}
}
}
I would encourage you to spend some time having a look at How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listeners for more details
After changing the value call
frame.repaint();
Good to see you learning Java! A few things I should point out.
Firstly, your variable names are good, but they don't follow the Java naming convention. Even though it seems small, it's just good practice to follow.
Of course, your actual problem; the action listener you've implemented is on the JFrame. (See how you extend JFrame and implement ActionListener?) This ActionListener should be on the button. You'll can do this a few ways.
Method 1: By adding it inline with your code
JButton heightButton = new JButton("Increase Height");
heightButton.addActionListener(new ActionListener(){
#Override
public void run(){
//run method here
}
});
Method 2: Create a class which implements ActionListener
class ButtonListener implements ActionListener{
#Override
public void run(){
//actionListener code here
}
}
And then instantiate an object of this type and add it directly to your code.
ActionListner buttonListener = new ButtonListener(); //or ButtonListener buttonListener = new ButtonListener();
JButton heightButton = new JButton("Increase Height");
heightButton.addActionListener(buttonListener);
Of course, as in MadProgrammers answer, don't forget to add the labels and such to your JFrame or JPanel. Good luck learning Java!
I bet that your program just shows nothing, isn't it? That's because in addComponentsToPane method, you didn't add any component but empty JPanels. After the comment //Adding Components to GridPanel, you should:
buttondraw.add(HeightIncrease);
buttondraw.add(HeightDecrease);
grid.add(height);
grid.add(width);
Then, to listen to button event, you should also add :
HeightIncrease.addActionListener(this);
HeightDecrease.addActionListener(this);
"this" is because your frame JFrameSetUp implements ActionListener, so when either bootton is clicked the method actionPerformed is invoked.
As JLabel.setText method will repaint itself and consequently its component hierarchi is repainted as well, you haven't to do anything othr.

JFrame not working - content does not appear

Not sure what my issue is. I created a JFrame and I have a panel that will have 4 large buttons (with graphics - though that isn't coded yet) to show on the frame but I am getting an error when it tries to run this and the panel isn't showing up in the frame.
UPDATED: No error message, but no panel or buttons in the frame...
public class EasyExpress {
private static JFrame frame = new JFrame("EASY BUTTONS");
private JButton WriteBTN = new JButton("Write Email");
private JButton EmailBTN = new JButton("View Emails");
private JButton SolBTN = new JButton("Play Solsuite Solitaire");
private JButton ShutBTN = new JButton("Shutdown Computer");
private JPanel btnPanel;
public EasyExpress() {
/* try {
Image img = ImageIO.read(getClass().getResource("write.jpg"));
WriteBTN.setIcon(new ImageIcon(img));
} catch (IOException ex) {
}*/
btnPanel = new JPanel(new GridLayout(1,4,1,1));
btnPanel.setBounds(0, 0, 1200, 400);
WriteBTN.setPreferredSize(new Dimension(300,400));
EmailBTN.setPreferredSize(new Dimension(300,400));
SolBTN.setPreferredSize(new Dimension(300,400));
ShutBTN.setPreferredSize(new Dimension(300,400));
btnPanel.add(EmailBTN);
btnPanel.add(WriteBTN);
btnPanel.add(SolBTN);
btnPanel.add(ShutBTN);
frame.add(btnPanel);
frame.add(frame);
}
public static void main(String[] args) {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setSize(1200,400);
frame.setVisible(true);
}
Essentially, you're adding a frame to another frame, which you simply can't do
You're also not initialising your buttons, which is causing a NullPointerException.
Start by removing extends JFrame, this is just confusing things and as general rule, you should avoid extending from top level containers. Instead, start with a JPanel, for example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class EasyExpress extends JPanel {
JButton WriteBTN, EmailBTN, SolBTN, ShutBTN;
JPanel btnPanel;
public EasyExpress() {
btnPanel = new JPanel(new GridLayout(1, 4, 1, 1));
btnPanel.setBounds(0, 0, 1200, 400);
WriteBTN = new JButton("1");
EmailBTN = new JButton("2");
SolBTN = new JButton("3");
ShutBTN = new JButton("4");
WriteBTN.setPreferredSize(new Dimension(300, 400));
EmailBTN.setPreferredSize(new Dimension(300, 400));
SolBTN.setPreferredSize(new Dimension(300, 400));
ShutBTN.setPreferredSize(new Dimension(300, 400));
btnPanel.add(EmailBTN);
btnPanel.add(WriteBTN);
btnPanel.add(SolBTN);
btnPanel.add(ShutBTN);
setLayout(new BorderLayout());
add(btnPanel);
}
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();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new EasyExpress());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Like #MadProgrammer mentioned in the comments above, you can't have a JFrame inside another JFrame.
However, instead of removing the extends JFrame, I would suggest removing the JFrame inside your EasyExpress object. You already set all the properties for that JFrame in your main, so it will be easier to fix.
Remove JFrame frame = new JFrame("EASY BUTTONS");
Add "EASY BUTTONS" to the EasyExpress object you create in main EasyExpress main = new EasyExpress("EASY BUTTONS");
Remove frame. from in front of frame.add(btnPanel);

JList position resets to default whenever update occurs

list is to accept input from Action1 this works, however, whenever a new element is added to the list, the list's position moves back to the default top-middle position.
This also occurs when the frame is resized, so as a temporary fix I the line frame.setResizable(false) but I do not want that to be permanent.
How would I fix both of these issues?
import static java.lang.String.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionListener;
public class lists
{
static String newUrl;
static DefaultListModel<String> model = new DefaultListModel<String>();
static int listXCoord = 650;
static int listYCoord = 10;
public static void createGUI()
{
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(800,600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel panel = new JPanel();
frame.add(panel);
JButton addurl = new JButton("Add URL");
panel.add(addurl);
addurl.addActionListener(new Action1());
JButton remurl = new JButton("Remove URL");
panel.add(remurl);
//model.addElement("one");
//model.addElement("two");
//model.addElement("three");
JList list = new JList<String>(model);
list.setCellRenderer(new DefaultListCellRenderer());
list.setVisible(true);
list.setLocation(listXCoord, listYCoord);
list.setBackground(new Color(186, 203, 250));
//list.setLocation(650, 10);
panel.add(list);
list.setSize(130, 540);
}
static class Action1 implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
newUrl = JOptionPane.showInputDialog("Enter the URL to be Launched");
model.addElement(newUrl);
}
}
public static void main(String[] args)
{
createGUI();
}
}
Basically, you're fighting the layout manager (Flowlayout) and losing. When you add a new element to the JList, the container hierarchy is been revalidated which is causing the layout managers to re-layout the contents of their containers
The basic solution would be to use a different layout, but, JFrame uses a BorderLayout, so instead of adding the JList to the JPanel, you could simply add it to the EAST position of the frame instead
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Lists {
static String newUrl;
static DefaultListModel<String> model = new DefaultListModel<String>();
static int listXCoord = 650;
static int listYCoord = 10;
public static void createGUI() {
JFrame frame = new JFrame();
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
JButton addurl = new JButton("Add URL");
panel.add(addurl);
addurl.addActionListener(new Action1());
JButton remurl = new JButton("Remove URL");
panel.add(remurl);
//model.addElement("one");
//model.addElement("two");
//model.addElement("three");
JList list = new JList<String>(model);
list.setCellRenderer(new DefaultListCellRenderer());
list.setVisible(true);
list.setLocation(listXCoord, listYCoord);
list.setBackground(new Color(186, 203, 250));
//list.setLocation(650, 10);
frame.add(new JScrollPane(list), BorderLayout.EAST);
frame.setVisible(true);
}
static class Action1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
newUrl = JOptionPane.showInputDialog("Enter the URL to be Launched");
model.addElement(newUrl);
}
}
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();
}
createGUI();
}
});
}
}
See Laying Out Components Within a Container, How to Use BorderLayout and How to use FlowLayout for more details.
You should also be calling setVisible last, after all the components have been added to the frame, this reduces the possibilities that some of your components won't be displayed when you think they should be.
JList will also benefit from been contained within a JScrollPane. See How to Use Lists and How to Use Scroll Panes for more details

Java EventHandling

When I compile it show error in line 33 : Cannot find symbol.
I am calling jbtNew.addActionListener(listener), so why it's unable to find jbtNew in
(e.getSource() == jbtNew) in line 33.
from code
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class AnonymousListenerDemo extends JFrame {
public AnonymousListenerDemo() {
// Create four buttons
JButton jbtNew = new JButton("New");
JButton jbtOpen = new JButton("Open");
JButton jbtSave = new JButton("Save");
JButton jbtPrint = new JButton("Print");
// Create a panel to hold buttons
JPanel panel = new JPanel();
panel.add(jbtNew);
panel.add(jbtOpen);
panel.add(jbtSave);
panel.add(jbtPrint);
add(panel);
// Create and register anonymous inner-class listener
AnonymousListenerDemo.ButtonListener listener = new AnonymousListenerDemo.ButtonListener();
jbtNew.addActionListener(listener);
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jbtNew) //Here it show the problem
{
System.out.println("Process New");
}
}
}
/** Main method */
public static void main(String[] args) {
JFrame frame = new AnonymousListenerDemo();
frame.setTitle("AnonymousListenerDemo");
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
That's a local variable.
It doesn't exist outside the constructor.
You need to make a field in the class.
this could be work (in the form as you posted here) and #SLaks mentioned +1, with a few major changes
in the case that all methods will be placed into separated classes to use put/getClientProperty()
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class AnonymousListenerDemo {
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame("AnonymousListenerDemo");
// Create four buttons
private JButton jbtNew = new JButton("New");
private JButton jbtOpen = new JButton("Open");
private JButton jbtSave = new JButton("Save");
private JButton jbtPrint = new JButton("Print");
public AnonymousListenerDemo() {
JPanel panel = new JPanel();// Create a panel to hold buttons
panel.add(jbtNew);
panel.add(jbtOpen);
panel.add(jbtSave);
panel.add(jbtPrint);
// Create and register anonymous inner-class listener
jbtNew.addActionListener(new ButtonListener());
frame.add(panel);
//frame.setTitle("AnonymousListenerDemo");
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jbtNew) {
System.out.println("Process New");
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new AnonymousListenerDemo();
}
});
}
}

Categories