How to set flow layout? - java

hi i am trying to make java desktop application where i am trying to make jbutton bottom left i did following code i dont know where i am wrong my code is note working
here is my code
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import javax.swing.*;
new complete code
public class ApplicationCloseExample
{
private JButton[] buttons;
private void displayGUI()
{
final JFrame frame = new JFrame("Application Close Example");
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
for (int i = 5; i < 8; i++) {
buttons[i] = new JButton(Integer.toString(i));
bottomPanel.add(buttons[i]);
}
// JButton button = new JButton("Comment");
// bottomPanel.add(button);
// frame.getContentPane().add(contentPane, BorderLayout.CENTER);
frame.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new ApplicationCloseExample().displayGUI();
}
});
}
}
How can i achieve this

I'm going to assume the null pointer exception is something to do with your buttons array. Check that you have initialised it properly.
private JButton[] buttons = new JButton[8];
I copied your code into a test project and ran it after some modifications:
public static void main(String[] args) {
final JFrame frame = new JFrame("Application Close Example");
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
for (int i = 5; i < 8; i++) {
buttons[i] = new JButton(Integer.toString(i));
bottomPanel.add(buttons[i]);
}
frame.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
This produced a frame with three buttons aligned to the bottom left of the window.

There is an elegant solution that I'll give you but maybe it serves. Use WindowsBuilder and adds several buttons and then you look like is placing code. So make yourself an idea of the pattern that follows a setLayout with Flow.

Related

Java Swing 13 GridLayout does not exist?

I can't seem to get a swing GridLayout to work in java 13. The error is that GridLayout cannot be resolved to a type in the following code:
import javax.swing.*;
public class GameFrame extends JFrame {
public static final void NewFrame() {
new GameFrame();
}
public GameFrame() {
this.setSize(1600, 800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("The Game");
this.setVisible(true);
this.setResizable(false);
JPanel MainPanel = new JPanel();
MainPanel.setLayout(new GridLayout());
}
}
The issue is caused by the class not being imported.
import java.awt.GridLayout;
Since it is not in the swing package it doesn't get imported with the star import.
Also it is better to use explicit imports.
This might be related to the fact that panel is empty. Try running this code and it should work.
public class GridLayoutTest {
private static JButton[] arrayBtn;
public static void main(String[] args) {
// the frame that contains the components
JFrame frame = new JFrame("GridLayoutTest from JCG");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set the size of the frame
frame.setSize(350, 350);
// set the rows and cols of the grid, as well the distances between them
GridLayout grid = new GridLayout(5, 3, 10, 10);
// what layout we want to use for our frame
frame.setLayout(grid);
// add a text field with a specified text to the frame
JTextArea text = new JTextArea();
text.setText("Result");
text.setEditable(false);
frame.add(text);
// add buttons to the frame
frame.add(new JButton("+"));
frame.add(new JButton("="));
arrayBtn = new JButton[10];
// add JButtons dynamically
for(int i=0; i < arrayBtn.length; i++) {
arrayBtn[i] = new JButton(Integer.toString(i));
frame.add(arrayBtn[i]);
}
frame.setVisible(true);
}
}

JButton in JPanel

I don't know why my grids cover my button I try to solve it out but I can't. Can anyone tell me why? Is it because, I put all together in BorderLayout? Any one can more the Play Button to the Right hand side of it ?
public game() {
make();
JPanel p = new JPanel();
frame.setLayout(new BorderLayout());
resetButton = new JButton("Play");
p.add(playButton, BorderLayout.EAST);
frame.add(p);
}
public void make(){
frame = new JFrame("Gamer");
frame.setTitle("Gamer");
JPanel m = new JPanel(new GridLayout(9,9));
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
grids[i][j] = new JButton();
m.add(grids[i][j]);
}
}
frame.add(m, BorderLayout.CENTER);
frame.setResizable(false);
frame.setSize(width, heigth);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
Essentially, you are adding both the m (grid) and button panel to the CENTER position of the BorderLayout
Here
frame.add(m, BorderLayout.CENTER);
and
p.add(playButton, BorderLayout.EAST);
frame.add(p); // adding to the CENTER position
The default position within the BorderLayout is the CENTER position. By simply using frame.add(p, BorderLayout.EAST);, you can can move the button to the right...
Beware, there are issues with using setResizable where it will change the border size of the frame, changing the available space for your frames content, always call this before defining the size of the frame, which should be done with pack
You really want to avoid modifying the content of the frame after it's been made visible if you can, as this not only affects the space the content might like, but also needs you to revalidate and repaint the container.
Better, create the frame, then pass it to the game and make methods instead...
Try to use frame.add(p,BorderLayout.SOUTH)
Here is an example.
The code:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class game {
JFrame frame;
JButton grids[][] = new JButton[9][9];
public game() {
make();
JPanel p = new JPanel();
JButton resetButton = new JButton("reset");
JButton playButton = new JButton("Play");
p.add(playButton);
p.add(resetButton);
frame.add(p,BorderLayout.SOUTH);
frame.setVisible(true);
}
public void make() {
frame = new JFrame("Gamer");
frame.setTitle("Gamer");
JPanel m = new JPanel(new GridLayout(9, 9));
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
grids[i][j] = new JButton();
m.add(grids[i][j]);
}
}
frame.add(m, BorderLayout.CENTER);
frame.setResizable(false);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
game gameObj = new game();
}
}
The effect:
Besides that,the first letter of the class name should be Capitalized.
Well, It is a matter of size. Literally, your grid and/or button are too big to fit where you want them to, so they leak into the next space. (i.e. BorderLayout.EAST will leak into BorderLayout.CENTER).
Try making your JFrame larger, and also try setting the preferred size of your JPanels to further assure a well built window.
You are using frame.add(p) - which may not add the panel to the correct area of the frame.
Try
frame.add(p, BorderLayout.SOUTH)
or whatever? i.e. not CENTER which would overwrite your grid.
Also note that the layout of the panel hasn't been set, so it will be a FlowLayout by default.
As MadProgrammer said, no need to set the layout of the frame - especially AFTER adding the grids!
Finally, it is good practice to only add to the getContentPane() of a frame.
Do you want this?
![enter image description here][1]import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class WelcomActivity {
JFrame frame;
JButton resetButton;
JButton playButton;
JButton[][] grids = new JButton[9][9];
int width = 600;
int heigth = 400;
public void game() {
make();
JPanel p = new JPanel();
playButton = new JButton("Play");
resetButton = new JButton("Reset");
p.add(playButton);
p.add(resetButton);
frame.getContentPane().add(p, BorderLayout.EAST);
}
public void make() {
frame = new JFrame("Gamer");
frame.setTitle("Gamer");
JPanel m = new JPanel(new GridLayout(9, 9));
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
grids[i][j] = new JButton();
m.add(grids[i][j]);
}
}
frame.setResizable(false);
frame.setSize(width, heigth);
frame.getContentPane().setLayout(new BorderLayout() );
frame.getContentPane().add(m, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args){
new WelcomActivity().game();
}
}

Set Location of Button on a Window

As practice, I've been trying to make a simple tic tac toe game to see how layouts work in java. Now that I have the base code, with all of the rules and variable checks, I cannot find out how to get the buttons to line up the way I want. I wanted to make a 3x3 grid of buttons, but whenever I try a tutorial online or find someone with a similar problem, it always leads to the buttons not showing up at all. The following code gets the buttons on the screen, but doesn't arrange them.
package game;
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JFrame{
//JPanel
JPanel pnlMainBoard = new JPanel();
//Buttons
JButton btnTest = new JButton("Test");
JButton btnAI = new JButton("A1");
JButton btnBI = new JButton("B1");
JButton btnCI = new JButton("C1");
JButton btnAII = new JButton("A2");
JButton btnBII = new JButton("B2");
JButton btnCII = new JButton("C2");
JButton btnAIII = new JButton("A3");
JButton btnBIII = new JButton("B3");
JButton btnCIII = new JButton("C3");
public Main(){
//Layout
//pnlMainBoard.setLayout(null);
//Game set bounds
btnTest.setBounds(60,400,220,30);
//JPanel bounds
pnlMainBoard.setBounds(800,800,200,100);
//Add buttons to frame
pnlMainBoard.add(btnTest);
pnlMainBoard.add(btnAI);
pnlMainBoard.add(btnBI);
pnlMainBoard.add(btnCI);
pnlMainBoard.add(btnAII);
pnlMainBoard.add(btnBII);
pnlMainBoard.add(btnCII);
pnlMainBoard.add(btnAIII);
pnlMainBoard.add(btnBIII);
pnlMainBoard.add(btnCIII);
add(pnlMainBoard);
//JFrame Properties
setSize(400,400);
setTitle("Ultimate Tic Tac Toe");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Main();
}
}
So far this is the only code I've created that successfully puts the buttons on the screen, and when I change it the buttons disappear. How do I make it so I can set the location of the buttons where I want them on the window?
For a 3x3 grid check out the swing grid layout that you can set the JPanel to use like this:
GridLayout grid = new GridLayout(3,3);
JPanel.setLayout(grid);
Where jpanel is the name of your jpanel in your program...
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class ThreeByThreeWithButtonLayout {
private JComponent ui = null;
ThreeByThreeWithButtonLayout() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
int gap = 10;
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
JButton testButton = new JButton("Test");
JPanel buttonConstrain = new JPanel(
new FlowLayout(FlowLayout.CENTER, gap, gap));
buttonConstrain.add(testButton);
ui.add(buttonConstrain, BorderLayout.PAGE_START);
JPanel gridPanel = new JPanel(new GridLayout(0, 3, 5, 5));
gridPanel.setBorder(new EmptyBorder(gap, gap, gap, gap));
ui.add(gridPanel, BorderLayout.CENTER);
String[] buttonRows = {"A", "B", "C"};
for (int ii = 1; ii < 4; ii++) {
for (String buttonRow : buttonRows) {
JButton b = new JButton(buttonRow + ii);
b.setFont(b.getFont().deriveFont(32f));
gridPanel.add(b);
}
}
}
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) {
}
ThreeByThreeWithButtonLayout o = new ThreeByThreeWithButtonLayout();
JFrame f = new JFrame("3x3 + Button");
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);
}
}
GridLayout makes some rows and columns to your frame/panel like this :
GridLayout grid = new GridLayout(3,3);
Jpanel.setLayout(grid);

Adding ScrollPane to JTextArea

I am working on a project for my college course. I was just wondering if anyone knew how to add a scrollBar to a JTextArea. At present I have the GUI laid out correctly, the only thing missing is the scroll bar.
This is what the GUI looks like. As you can see on the second TextArea I would like to add the Scrollbar.
This is my code where I create the pane. But nothing seems to happen... t2 is the JTextArea I want to add it to.
scroll = new JScrollPane(t2);
scroll.setBounds(10,60,780,500);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
Any help would be great, thanks!
The Scroll Bar comes when your text goes beyond the bounds of your view area. Don't use Absolute Positioning, for such a small talk at hand, always prefer Layout Managers, do read the first para of the first link, to know the advantage of using a Layout Manager.
What you simply need to do is use this thingy :
JTextArea msgArea = new JTextArea(10, 10);
msgArea.setWrapStyleWord(true);
msgArea.setLineWrap(true);
JScrollPane msgScroller = new JScrollPane();
msgScroller.setBorder(
BorderFactory.createTitledBorder("Messages"));
msgScroller.setViewportView(msgArea);
panelObject.add(msgScroller);
Here is a small program for your understanding :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JTextAreaScroller
{
private JTextArea msgArea;
private JScrollPane msgScroller;
private JTextArea logArea;
private JScrollPane logScroller;
private JButton sendButton;
private JButton terminateButton;
private Timer timer;
private int counter = 0;
private String[] messages = {
"Hello there\n",
"How you doing ?\n",
"This is a very long text that might won't fit in a single line :-)\n",
"Okay just to occupy more space, it's another line.\n",
"Don't read too much of the messages, instead work on the solution.\n",
"Byee byee :-)\n",
"Cheers\n"
};
private ActionListener timerAction = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (counter < messages.length)
msgArea.append(messages[counter++]);
else
counter = 0;
}
};
private void displayGUI()
{
JFrame frame = new JFrame("Chat Messenger Dummy");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(0, 1, 5, 5));
logArea = new JTextArea(10, 10);
logArea.setWrapStyleWord(true);
logArea.setLineWrap(true);
logScroller = new JScrollPane();
logScroller.setBorder(
BorderFactory.createTitledBorder("Chat Log"));
logScroller.setViewportView(logArea);
msgArea = new JTextArea(10, 10);
msgArea.setWrapStyleWord(true);
msgArea.setLineWrap(true);
msgScroller = new JScrollPane();
msgScroller.setBorder(
BorderFactory.createTitledBorder("Messages"));
msgScroller.setViewportView(msgArea);
centerPanel.add(logScroller);
centerPanel.add(msgScroller);
JPanel bottomPanel = new JPanel();
terminateButton = new JButton("Terminate Session");
terminateButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (timer.isRunning())
timer.stop();
else
timer.start();
}
});
sendButton = new JButton("Send");
bottomPanel.add(terminateButton);
bottomPanel.add(sendButton);
contentPane.add(centerPanel, BorderLayout.CENTER);
contentPane.add(bottomPanel, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, timerAction);
timer.start();
}
public static void main(String... args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new JTextAreaScroller().displayGUI();
}
});
}
}
Here is the outcome of the same :
The scroll bar by default will only be shown when the content overfills the available viewable area
You can change this via the JScrollPane#setVerticalScrollBarPolicy method, passing it ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS

Adding JPanels to JPanel array

I have declared an array:
private javax.swing.JPanel[] panelArray = new javax.swing.JPanel[3];
I also have 3 panels: panel0, panel1 and panel2. Can I add these panels to the array? i.e
panelArray[0] = panel0;
panelArray[1] = panel1;
panelArray[2] = panel2;
And then manipulate the arrays like this?
boolean[] myBools; .... then set them as true/false
for(int i=0; i<3; i++)
{
if(myBools[i])
panelArray[i].setVisible(true)
}
Because that does not work for me
On my side it's working fine, in this program :
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class MyPanel
{
private JPanel[] panelArray = new JPanel[3];
private boolean[] myBools = new boolean[]{false, false, false};
private int counter = 0;
private int prvPanelCounter = 0;
private Timer timer;
private ActionListener timerAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
counter++;
if (counter > 2)
counter = 0;
myBools[counter] = true;
for (int i = 0; i < 3; i++)
{
if (myBools[i])
{
panelArray[i].setVisible(myBools[i]);
panelArray[prvPanelCounter].setVisible(myBools[prvPanelCounter]);
myBools[i] = false;
prvPanelCounter = i;
break;
}
}
}
};
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Locate Mouse Position");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel0 = new JPanel();
panel0.setOpaque(true);
panel0.setBackground(Color.BLUE);
JPanel panel1 = new JPanel();
panel1.setOpaque(true);
panel1.setBackground(Color.RED);
JPanel panel2 = new JPanel();
panel2.setOpaque(true);
panel2.setBackground(Color.DARK_GRAY);
panelArray[0] = panel0;
panelArray[1] = panel1;
panelArray[2] = panel2;
JComponent contentPane = (JComponent) frame.getContentPane();
contentPane.setLayout(new GridLayout(0, 1));
frame.add(panel0);
frame.add(panel1);
frame.add(panel2);
panel0.setVisible(myBools[counter]);
panel1.setVisible(myBools[counter]);
panel2.setVisible(myBools[counter]);
frame.setSize(300, 300);
frame.setLocationByPlatform(true);
frame.setVisible(true);
timer = new Timer(1000, timerAction);
timer.start();
}
public static void main(String\u005B\u005D args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new MyPanel().createAndDisplayGUI();
}
});
}
}
What you want to do can be done, but here's a few points to bear in mind:
Make sure you initialise the JPanels before referencing them.
The statement "panelArray[i].setVisible(true)" needs a semicolon after it.
None of these panels will be visible unless you add them to another component, such as a JFrame.
Rather than state javax.swing.JPanel, you could just import the JPanel at the top of the page and refer to it as simply JPanel.
Your "if" statement is unnecessary. Just do .setVisible(myBools[i]);
Hope these were of some help to you.
Yes, you can. Did you really not initialize the myBools array with new ?

Categories