First of all I looked around stackoverflow and I didnt find anything related to my problem.
Im trying to use the GridBagLayout, the first time I tried it it was functioning, but I dont know what I did, that now it doesnt displays anything, do you have any idea of mas happening??
Heres all code:
package Instrucciones;
import java.awt.*;
import javax.swing.*;
/**
*
* #author Antonio
*/
public class JDialog1TxArea extends JDialog {
JPanel panel = new JPanel(); //Contains all objects
JTextArea instruc;
JButton ok;
public JDialog1TxArea(String instrucciones){
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle("Instrucciones");
pack();
setSize(450,300);
setLocationRelativeTo(null);
setVisible(true);
JPanel mainpanel = new JPanel();
getContentPane().add(mainpanel);
panel = new JPanel();
panel.setLayout(new GridBagLayout());
mainpanel.add(panel);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.CENTER;
instruc = new JTextArea(instrucciones);
ok = new JButton("Aceptar");
panel.add(instruc, c);
c.gridy++;
panel.add(ok, c);
c.gridy++;
}
public static void main (String args[]){
JDialog1TxArea v = new JDialog1TxArea("Conalep");
}
}
The console doesnt have any exception.
Move setVisible to the last line in the constructor
public JDialog1TxArea(String instrucciones) {
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setTitle("Instrucciones");
// From here
//pack();
//setSize(450, 300);
//setLocationRelativeTo(null);
//setVisible(true);
JPanel mainpanel = new JPanel();
getContentPane().add(mainpanel);
panel = new JPanel();
panel.setLayout(new GridBagLayout());
mainpanel.add(panel);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.CENTER;
instruc = new JTextArea(instrucciones);
ok = new JButton("Aceptar");
panel.add(instruc, c);
c.gridy++;
panel.add(ok, c);
c.gridy++;
// To here
pack();
setLocationRelativeTo(null);
setVisible(true);
}
I'd like to disencourage you from extending from top level containers like JDialog and instead design your UI's using JPanel as your base container. You can then add these to what ever top level container you want, even, in your case, using something like JOptionPane. See How to Make Dialogs for more details
You may also want to have a look at How to Use Scroll Panes, as your JTextArea will benefit from it
Related
My partner and I are writing this program for a game. He used GridBagLayout for our grid and I'm trying to troubleshoot some problems with the grid.
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
#SuppressWarnings("serial")
public class NewGame extends JFrame{
private int width = 500, height = 500, xSquares = 4, ySquares = 4;
Font buttonFont = new Font("Times New Roman", Font.PLAIN, 15);
endGame end = new endGame();
public NewGame() {
super("OnO");
// gridbaglayout is flexible but kinda complicated
GridBagLayout Griddy = new GridBagLayout();
this.setLayout(Griddy);
JPanel p = new JPanel();
p.setLayout(Griddy);
this.add(p);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 4;
c.gridheight = 4;
NewBoard board = new NewBoard(xSquares, ySquares);
// board at top left
c.gridx = 0;
c.gridy = 0;
this.add(board, c);
// find a way to make buttons smaller
JButton EndGame = new JButton("End");
EndGame.setBackground(Color.black);
EndGame.setForeground(Color.white);
EndGame.setFont(buttonFont);
EndGame.addActionListener(end);
JButton Undo = new JButton("Undo");
Undo.setBackground(Color.black);
Undo.setForeground(Color.white);
Undo.setFont(buttonFont);
JButton NewGame = new JButton("New Game");
NewGame.setBackground(Color.black);
NewGame.setForeground(Color.white);
NewGame.setFont(buttonFont);
// fit 3
c.gridwidth = 1;
c.gridheight = 1;
c.gridy = 3;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(EndGame, c);
c.gridx = 2;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(Undo, c);
c.gridx = 3;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(NewGame, c);
this.setPreferredSize(new Dimension(width, height));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
this.setLocation(450, 30);
this.setVisible(true);
}
public class endGame implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
}
public class newGame implements ActionListener {
public void actionPerformed(ActionEvent event) {
}
}
}
When this code is run with the other classes in our program, the endGame, Undo, and NewGame buttons overlap with the board:
I want to find a way to display the 3 buttons either above or below the board in its individual space, but I've tinkered with the code for a long time and can't find the solution yet. I'm not sure what I should be doing here.
First of all, variable names should NOT start with an upper case character. Learn and follow Java naming conventions.
I want to find a way to display the 3 buttons either above or below the board
Simplest solution is to not use a GridBagLayout for the frame.
Just use the default BorderLayout of the frame. Then you can use a JPanel with the FlowLayout for your buttons, and a GridLayout for your board panel.
The basic logic would be:
JPanel buttons = new JPanel();
buttons.add(endGame);
buttons.add(undo);
buttons.add(newGame);
this.add(button, BorderLayout.PAGE_START);
NewBoard board = new NewBoard(xSquares, ySquares);
this.add(board, BorderLayout.CENTER);
By default a JPanel uses a FlowLayout so the buttons will be displayed on a single row.
Read the Swing tutorial on Layout Managers for more information and working examples to better understand how this suggestion works.
I'm new here.
I wrote a simple program in Java and for the GUI I'm using GridBagLayout.
The problem is that it doesn't paginate well until I touch the border of the window to resize the Frame. Here are some pictures of what I mean:
The main window before I resize the frame
The main window after I resize the frame
A part of my code:
public class TW2Tempi
{
public static void main(String[] args)
{
MainFrame mf = new MainFrame();
}
}
class MainFrame extends JFrame
{
GridBagConstraints gbc = new GridBagConstraints();
//other variables .....
public MainFrame()
{
super("Calcola i tempi dei tuoi attacchi");
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridBagLayout());
setPreferredSize(new Dimension(500, 300));
setMinimumSize(new Dimension(500, 300));
//setResizable(false); //I would also like to add this but then I wouldn't be able to "resize" and see everything (second picture)
//row 1 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//where gbc.gridy = 0
nobile = new JLabel("Orario di arrivo del nobile", SwingConstants.RIGHT);//right align
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.insets = new Insets(7,10,0,0);
gbc.fill = GridBagConstraints.BOTH;
add(nobile, gbc);
....
Do I have to initialize GridBagConstraints in a different way?
(Sorry if this question is not done properly, I'm new. But at least I researched a lot before asking my own question)
Hello. I'm writing a blackjack game in java and it's turning quite massive. My problem is how to handle multiple instances of swing components, I guess you can call it. I can't figure out wether to create the components (such as jpanels and jbuttons) as class level, or in specific methods.
If I create them in their corresponding method, then my action listener can't see them, but if I create them as class level, then they get deleted when I call dispose().
class BlackjackGame extends JFrame implements ActionListener{
public void mainMenu(){
JPanel menuPane = new JPanel(new GridBagLayout()); //Init of main menu
GridBagConstraints c = new GridBagConstraints();
menuPane.setBackground(new Color(125,0,0));
menuPane.setBounds(620,220,175,250);
JLabel menuTitle = new JLabel("Welcome to Blackjack!");//Main menu-content
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,0,20,0);
menuPane.add(menuTitle, c);
JButton playButton = new JButton("Play!");
playButton.addActionListener(this);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
c.ipadx = 25;
c.ipady = 25;
c.insets = new Insets(0,0,0,0);
menuPane.add(playButton, c);
JButton exitButton = new JButton("Exit!");
exitButton.addActionListener(this);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 3;
menuPane.add(exitButton, c);
JButton rulesButton = new JButton("Set rules.");
rulesButton.addActionListener(this);
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 3;
menuPane.add(rulesButton, c);
this.add(menuPane,0);
}
//This is where I get problems
public void actionPerformed (ActionEvent event){
if(event.getSource() == playButton){
//I want the menuPane to disappear, and a transition into the game.
menuPane.dispose();
//Call method for the rest of the game.
}else if(event .getSource() etcetera etcetera){
etcetera etcetera
}
}
}
When done this way, the actionlistener cannot find my components, such as playButton or menuPane. But if I had introduced them as class level objects:
class BlackjackGame extends JFrame implements ActionListener{
JPanel menuPane = new JPanel(new GridBagLayout());
JLabel menuTitle = new JLabel("Welcome to Blackjack!");
JButton playButton = new JButton("Play!");
JButton exitButton = new JButton("Exit!");
JButton rulesButton = new JButton("Set rules.");
public void mainMenu(){
//Rest of code
}
public void actionPerformed(ActionEvent event){
menuPane.dispose();
//Rest of code
}
}
...then as I call menuPane.dispose(), how can I get it back when I want to call mainMenu() again? If I want to go back to the main menu, then I would need to create a new instance of menuPane, as well as all the buttons, but as they are class level and already disposed I can't.
Please help me, and thank you!
PS. I can post my full code as it is atm if it would help.
Edit: Dan's answer has been accepted, as it was indeed the correct answer and it worked for my specific program very well. Thank you and merry christmas!
First, unless I've misunderstood your code, menuPane.dispose() shouldn't work as JPanel does not have a function called dispose()
The best way to do what you want to do if you want to use the same menuPane for the menu. Instead of menuPane.dispose(); use remove(menuPane); and then add(yourOtherPanel);
Working Example
import java.awt.Color;
import java.awt.EventQueue;
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.JLabel;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class BlackjackGame extends JFrame implements ActionListener {
private JPanel menuPane;
private JLabel menuTitle;
private JButton playButton;
private JButton exitButton;
private JButton rulesButton;
private JPanel otherPane;
private JLabel otherTitle;
private JButton otherButton;
public BlackjackGame() {
mainMenu();
otherPanel();
setSize(400, 400);
setVisible(true);
}
private void mainMenu() {
menuPane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
menuPane.setBackground(new Color(125,0,0));
menuPane.setBounds(620,220,175,250);
menuTitle = new JLabel("Welcome to Blackjack!");
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,0,20,0);
menuPane.add(menuTitle, c);
playButton = new JButton("Play!");
playButton.addActionListener(this);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
c.ipadx = 25;
c.ipady = 25;
c.insets = new Insets(0,0,0,0);
menuPane.add(playButton, c);
exitButton = new JButton("Exit!");
exitButton.addActionListener(this);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 3;
menuPane.add(exitButton, c);
rulesButton = new JButton("Set rules.");
rulesButton.addActionListener(this);
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 3;
menuPane.add(rulesButton, c);
add(menuPane);
}
private void otherPanel() {
otherPane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
otherPane.setBackground(new Color(125,0,0));
otherPane.setBounds(620,220,175,250);
otherTitle = new JLabel("Welcome to Second Pane!");
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,0,20,0);
otherPane.add(otherTitle, c);
otherButton = new JButton("Go Back!");
otherButton.addActionListener(this);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 3;
c.ipadx = 25;
c.ipady = 25;
c.insets = new Insets(0,0,0,0);
otherPane.add(otherButton, c);
}
public void actionPerformed (ActionEvent event) {
if(event.getSource() == playButton) {
remove(menuPane);
add(otherPane);
validate();
repaint();
} else if(event.getSource() == otherButton) {
remove(otherPane);
add(menuPane);
validate();
repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new BlackjackGame());
}
}
Edit for comments
So the java method remove() only removes the object from the container, which in this case is the JFrame. This method does not effect the object it moves so the object can be reused later. Hence why in the code above I can just use the remove() and add() methods without redeclaring or remaking menuPane and otherPane.
As for why I declare the objects like this
`private JPanel menuPane;`
And then initialize like this
menuPane = new JPanel(new GridBagLayout());
This is because I want the ActionListener to be able to see the objects without initializing them straight away. The line private JPanel menuPane; makes the object a global variable and the line menuPane = new JPanel(new GridBagLayout()); makes it into what I am going to use. Doing it this way instead of JPanel menuPane = new JPanel(new GridBagLayout()); also means I can reuse the same variable in multiple methods. For example
private JPanel panel;
private void createPanelOne() {
panel = new JPanel(new FlowLayout());
...
add(panel);
}
private void createPanelTwo() {
panel = new JPanel(new GridBagLayout());
...
add(panel);
}
After doing this, you will have two JPanels in your JFrame and they will be different, but you only need to use one JPanel
This is the other way of declaring it and it makes a local variable. Local variables aren't visible to other methods outside of the method you are using unless you pass them through.
JPanel panel = new JPanel();
I wouldn't say this is a con in the slightest. I think sometimes it is good to use local variables in a method that shouldn't be visible to other methods.
Finally to pass local variables through to other methods you can use arguments in a method you have made. For example
public void setSomeValue(int val) {
someValue = val;
}
I am trying to align a button using the GridBagLayout but it look I just can't achieve that. Also I want to remove the JButton's texture from my custom button, but I can not.. This is what it looks like:
I want the buttons to be at the top( but using GridBagLayout) and also on the left and right margin of the green button there is the remains of the JButton style and I can't remove it completely.
Also, this is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestPanel{
public TestPanel(){
JFrame frame = new JFrame();
frame.add(new Panel1());
frame.setVisible(true);
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestPanel();
}
public class Panel1 extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
public Panel1(){
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
ImageIcon im = new ImageIcon("Start.png");
ImageIcon i = new ImageIcon("Start-Pressed.png");
JButton button = new JButton(im);
JButton but = new JButton("BUT");
button.setRolloverEnabled(true);
Insets margin = new Insets(-15,-10,-10,-10);
button.setBorderPainted(false);
button.setMargin(margin);
button.setRolloverIcon(i);
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx=0.5;
c.gridx=0;
c.gridy=0;
add(button, c);
c.gridx=2;
c.gridy=1;
add(but,c);
}
}
}
Edit:
c.gridy++;
c.fill = GridBagConstraints.VERTICAL;
c.weighty = 1;
c.add(new JLabel(" "),c);
c.gridy++;
c.weighty = 1;
c.fill = GridBagConstraints.NONE;
add(eButton, c);
You can achive it with help of dummy JLabel at bottom, like next(add to the end of constructor):
c.gridy++;
c.fill = GridBagConstraints.VERTICAL;
c.weighty = 1;
add(new JLabel(" "), c);
To remove margin you can try setContentAreaFilled() method
Instead of ImageIcon im = new ImageIcon("Start.png"); use ImageIcon im = new ImageIcon(Panel1.class.getResource("Start.png"));
Also see that answer.
I have 3 JPanels and I want to place them all in one JPanel. I used the GridBagLayout for the main panel. But only one panel is getting added. Why might this be?
gblayout=new GridBagLayout();
gbc=new GridBagConstraints();
panel1Customizer();
panel2customizer();
panel3Customizer();
setLayout(gblayout);
gbc.fill=GridBagConstraints.HORIZONTAL;
gbc.anchor=GridBagConstraints.NORTHWEST;
gbc.weightx=1;
gbc.weighty=1;
gbc.gridheight=GridBagConstraints.REMAINDER;
add(panel1, gbc);
add(panel2, gbc);
gbc.gridwidth=GridBagConstraints.REMAINDER;
add(panel3, gbc);
The customizer methods are ones which add items into these panels.
I am not sure but I think you need to add a GridBagConstraints to your GridBagLayout. Try look at this site to get the idea on how to work with GridBagLayout:
link
Or maybe just use another Layout for your JFrame, maybe BorderLayout or GridLayout to arrange your Panels correctly
You should change gbc.gridx and/or gbc.gridy to be different for each panel
you have to read How to Use GridBagLayout, examples for that here and GridBagConstraints, change your gbc.fill=GridBagConstraints.HORIZONTAL;, if you have problem(s) with JComponent's Size then add setPreferedSize(); for example
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.*;
public class GBLFillBoth extends JFrame {
private static final long serialVersionUID = 1L;
public GBLFillBoth() {
JPanel panel = new JPanel();
GridBagLayout gbag = new GridBagLayout();
panel.setLayout(gbag);
GridBagConstraints c = new GridBagConstraints();
JButton btn1 = new JButton("One");
c.fill = GridBagConstraints.BOTH;
//c.fill = GridBagConstraints.HORIZONTAL;
c.anchor=GridBagConstraints.NORTHWEST;
c.gridx = 0;
c.gridy = 0;
c.weightx = 0.5;
c.weighty = 0.5;
panel.add(btn1, c);
JButton btn2 = new JButton("Two");
c.gridx++;
panel.add(btn2, c);
//c.fill = GridBagConstraints.BOTH;
JButton btn3 = new JButton("Three");
c.gridx = 0;
c.gridy++;
c.gridwidth = 2;
panel.add(btn3, c);
add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
GBLFillBoth gBLFillBoth = new GBLFillBoth();
}
}
You might consider using a MigLayout instead, the code is much simpler:
panel1Customizer();
panel2customizer();
panel3Customizer();
setLayout(new MigLayout("fill, wrap 3"));
add(panel1, "grow");
add(panel2, "grow");
add(panel3, "grow");