I'm trying to learn how to code Conway's game of life in Java, and I'm getting stuck creating the GUI. I want to make a JPanel within the JFrame, with a larger border at South, and then two buttons in the south border, one for "Play" and one for "Restart." But the Design element won't let me resize or move anything around. I was able to resize the JPanel by going into the code and creating a larger border in the South, but I can't figure out how to resize the JButton. Any ideas?
(I'm using Eclipse Kepler...I hear NetBeans is better at this kind of stuff, should I just ditch Eclipse and try it with NetBeans?)
Here's my code so far:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.JButton;
public class GameOfLife extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
GameOfLife frame = new GameOfLife();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public GameOfLife() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 518, 508);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(10, 10, 50, 10));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
JPanel panel = new JPanel();
panel.setBackground(Color.GRAY);
contentPane.add(panel, BorderLayout.CENTER);
JButton btnNewButton = new JButton("New button");
contentPane.add(btnNewButton, BorderLayout.SOUTH);
}
}
Basically, instead of doing BorderLayout.SOUTH, I want to manually place it where I want it within the frame. I'd also love to be able to do that with the JPanel--the whole North/West/South/East/Center thing in general seems very constricting. What's the way around it?
Maybe you should look at Swing Layouts in Java documentation:
A Visual Guide to Layout Managers
And the layout which is able to give you the most flexibility is the GridBagLayout but you will write much code to display the User Interface as your needs.
You will have a detailled way to go with the following official tutorial:
How to Use GridBagLayout
In your code, you are using the simple BorderLayout which is very simple but not so much configurable.
Related
I am currently working on a N-Body simulation and I have made particles move on a black screen. My current problem is that there is no way of controlling it.
My plan:
Each color stands for a different JPanel. The blue one should contain the buttons and text fields, the red one the viewport.
But with my small knowledge in Java, I didn't succeed in creating this. I first tried with setBounds and setLayoutManager(null), in vain.
My structure goes like that:
Window class extends JFrame
Simulation class creating blueJPanel class (extends JPanel) and redJPanel,
adds them to the window.
But this is garbage code... So how would you draw these simple panels on top of each other?
Oracle has a helpful tutorial, Creating a GUI With Swing. Skip the Learning Swing with the NetBeans IDE section. Pay particular attention to the Laying Out Components Within a Container section.
As I said in my comment, you create two JPanels. Here's an example.
Here's the complete runable code to create this example.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BorderLayoutExampleGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new BorderLayoutExampleGUI());
}
#Override
public void run() {
JFrame frame = new JFrame("BorderLayout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createButtonPanel(), BorderLayout.NORTH);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
panel.setPreferredSize(new Dimension(600, 100));
panel.setBackground(Color.blue);
// Add the buttons and text fields
return panel;
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
panel.setPreferredSize(new Dimension(600, 380));
panel.setBackground(Color.red);
// Add the drawing code
return panel;
}
}
Im creating a Tic Tac Toe game out of Java and i seem to be stucj in one problem i cant get out of :( . I cant rezize my button. I tried both tried both setSize and setPreferredSize but dosent seem to work:
Here is the setPreferedSize pic:
And Code:
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import sun.org.mozilla.javascript.internal.xml.XMLLib.Factory;
public class TicTacToe {
JFrame frame;
JPanel contentPane;
JButton row1col1;
JButton row1col2;
JButton row1col3;
JButton row2col1;
JButton row2col2;
JButton row2col3;
JButton row3col1;
JButton row3col2;
JButton row3col3;
public TicTacToe() {
// TODO Auto-generated constructor stub
frame = new JFrame("Fds");
contentPane = new JPanel();
contentPane.setLayout(new BoxLayout(contentPane,BoxLayout.Y_AXIS));
row1col1 = new JButton();
row1col1.setPreferredSize(new Dimension(600,600));
contentPane.add(row1col1);
row1col2 = new JButton();
row1col2.setPreferredSize(new Dimension(600,600));
contentPane.add(row1col2);
frame.setContentPane(contentPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private static void runGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
TicTacToe greeting = new TicTacToe();
}
public static void main(String[] args) {
/* Methods that create and show a GUI should be
run from an event-dispatching thread */
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
runGUI();
}
});
}
}
Thank you so much for your help!
The BoxLayout respects the maximum size of the component.
In your case the maximum size is less than the preferred size.
However, the solution is NOT to play with the preferred/maximum sizes.
Instead you can use:
button.setMargin( new Insets(10, 10, 10, 10) );
to control the size of your button, then normal layout management can be done as the preferred size will be calculated correctly.
As Camickr states, BoxLayout respects maximal size, but having said that, why use BoxLayout? Instead I suggest:
If you want to create a grid of JButtons, use GridLayout as it excels at creating grids.
It somewhat respects preferred sizes as long as you pack your GUI, and all the components are the same size,
But having said that, don't set the size. For tic tac toe, set the JLabel's font to something large, or use JLabels with ImageIcons that are large, so that your GUI sets its own size correctly.
You should be using an array or 2D array of JButtons for ease of coding.
For example please check out my code here: Java: Drawing using Graphics outside the class which draws the main canvas which uses programmer created ImageIcons and creates this GUI:
Or my code in this answer: How to wait for a MouseListener mouse press? which uses Font sizing to create this GUI:
I am writing a small Swing program which involves embedding a video player in the interface. In order to achieve this, I am using vlcj.
While the GUI itself has some more components, here is an analog code structure:
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import javax.swing.*;
import java.awt.*;
public class MyTestClass extends JFrame {
public MyTestClass(){
EmbeddedMediaPlayerComponent playerCmpt =
new EmbeddedMediaPlayerComponent();
playerCmpt.setPreferredSize(new Dimension(200, 100));
JPanel leftPane = new JPanel();
leftPane.setPreferredSize(new Dimension(100, 100));
JSplitPane mainSplit = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT,
leftPane, playerCmpt);
this.add(mainSplit);
this.pack();
this.setVisible(true);
}
public static void main(String[] args){
new MyTestClass();
}
}
(I tried this code separately, and I'm facing the same problem as in my GUI)
Basically, the window has two parts: a left panel in which I display some data, and a right panel in which the video is to be embedded. The panels are put together in a JSplitPane is order to allow the user to allocate the amount of room he desires for the player (and therefore, for the video itself). At first, the components get 100 and 200 pixels in width, respectively.
The problem is: EmbeddedMediaPlayerComponent is getting a little too confortable. While I have set it to a preferred size of 200x100, it refuses to shrink down once the vertical split has been moved. That is, I can't bring the player below 200 pixels in width, and once I've enlarge it, I can't bring it back to 200 pixels... Setting a maximum size doesn't change anything. This little problem is annoying because it forces my left panel to shrink again and again, until it becomes practically invisible.
Is there any way I could have the media player follow the constraints set by JSplitPane as the user tries to resize the components? If it's any use, the left pane contains a JTree in my application, which also gets crushed by the player.
This one works for me. Just improve the code to fit for your purpose.
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import java.awt.*;
import javax.swing.*;
import uk.co.caprica.vlcj.binding.LibVlc;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
public class MyTestClass extends JFrame {
public MyTestClass() {
String vlcPath = "C:\\Program Files (x86)\\VideoLAN\\VLC";
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcPath);
Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
EmbeddedMediaPlayerComponent playerCmpt = new EmbeddedMediaPlayerComponent();
playerCmpt.setPreferredSize(new Dimension(200, 100));
JPanel leftPane = new JPanel();
leftPane.setPreferredSize(new Dimension(100, 100));
JPanel playerPanel = new JPanel(new BorderLayout());
playerPanel.add(playerCmpt);
JSplitPane mainSplit = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT,
leftPane, playerPanel);
playerPanel.setMinimumSize(new Dimension(10, 10));
this.add(mainSplit);
this.pack();
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new MyTestClass();
}
}
I'm new in Java GUI programming and I have a strange issue with the BoxLayout:
I have an JLabel with an Icon. Added to the label are two JButtons. The Jlabel is placed in the CENTER position of the BorderLayout from a JFrame. Now I want that these two JButtons are always in the center of the JLabel even when I resize the JFrame. With setAlignmentX() the Jbuttons are centered horizontally , but there is no solution with setAlignmentY() for the vertical direction.
here is the code:
package footballQuestioner;
import java.awt.BorderLayout;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Houdini {
public static void main(String[] args) {
JFrame frame = new House();
}
}
class House extends JFrame {
private JLabel label = new JLabel(
new ImageIcon(
"C:\\Users\\laudatio\\Documents\\Java\\MyProject\\src\\footballQuestioner\\footballfield.jpg")
);
private JButton one=new JButton("one");
private JButton two=new JButton("two");
public House() {
label.setLayout(new BoxLayout(label, BoxLayout.Y_AXIS));
label.add(one);
label.add(two);
one.setAlignmentX(CENTER_ALIGNMENT);
one.setAlignmentY(CENTER_ALIGNMENT);
two.setAlignmentX(CENTER_ALIGNMENT);
two.setAlignmentY(CENTER_ALIGNMENT);
setLayout(new BorderLayout());
setLocation(300, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(true);
add(label,BorderLayout.CENTER);
pack();
setVisible(true);
}
}
Please Help! :-((((
but there is no solution with setAlignmentY() for the vertical direction.
Use "glue" before and after your two components. See the section from the Swing tutorial on How to Use Box Layout for more information and examples.
Although MadProgrammers comment to use a GridBagLayout is an easier solution, but knowing about "glue" and "struts" can be helpful for customizing the layout of a BoxLayout.
I am attempting to learn more about creating more dynamic GUI's. I am hoping to add different panels with different content and as you press buttons on one main panel, it changes the adjacent panels. I have added two panels and some buttons and when I test the program, it displays correctly. The problem is when I add a JTextField (or JTextArea) the panels are blank and there are no buttons. The strange thing is I haven't added the JTextField to either panel. I have only created a global variable. If I comment it out, the program runs correctly. Am I missing something very simple?
Here is the gameWindow class that has the JTextField
package rpgcreator;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
class gameWindow extends JPanel {
JPanel startWindowPanel;
JPanel settingsPanel;
JPanel characterPanel;
JPanel scenarioPanel;
JPanel mapPanel;
JButton CharacterButton = new JButton("Create your character");
JButton StoryButton = new JButton("Choose your Story line");
JButton MapButton = new JButton("Choose your World");
//JTextField nameField = new JTextField(15); //comment or uncomment to see issue
public gameWindow() {
setLayout(new GridLayout(0,2,5,0));
startWindowPanel = new JPanel(new FlowLayout());
settingsPanel = new JPanel(new GridLayout(2,1));
startWindowPanel.setBackground(Color.blue);
settingsPanel.setBackground(Color.black);
startWindowPanel.add(MapButton);
startWindowPanel.add(StoryButton);
startWindowPanel.add(CharacterButton);
add(startWindowPanel);
add(settingsPanel);
}
}
Here is main
package rpgcreator;
import javax.swing.JFrame;
public class RPGCreator extends JFrame{
private static void mainWindow(){
RPGCreator mainwindow = new RPGCreator();
mainwindow.setSize(1200, 800);
mainwindow.setResizable(false);
mainwindow.setLocationRelativeTo(null);
mainwindow.setTitle("RPG Creator");
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
mainwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
// TODO code application logic here
mainWindow();
}
}
setVisible should go at the end. You're currently setting visible to true, and then adding a panel.
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
Put setVisible at the end after setDeaultCLoseOperation
I'm not entirely sure why it does it, maybe someone else can explain.
What I do know, is I usually call pack() which seems to make your problem go away.
private static void mainWindow(){
final RPGCreator mainwindow = new RPGCreator();
mainwindow.setMinimumSize(new Dimension(1200, 800));
mainwindow.setResizable(false);
mainwindow.setTitle("RPG Creator");
mainwindow.setVisible(true);
mainwindow.add(new gameWindow());
mainwindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainwindow.pack(); //This usually goes after you've added all of your components
mainwindow.setLocationRelativeTo(null);
}
Some notes:
I had to change to mainwindow.setMinimumSize(new Dimension(1200, 800)); to avoid the frame looking squashed. Although I would usually let the layout manager deal with the sizes of things.
Call setLocationRelativeTo(null) after you call pack() so that it has the desired effect. Again not sure why, but I've learnt that through some hardship.