Struggling with BoxLayout in Java Swing - java

Whats up guys I'm struggling to understand how to implement BoxLayout or any layout in java swing. I have been looking at tutorials on oracle and others but i just can't get it to work. This is for an assignment in college so I would appreciate not giving me the solution straight up but maybe just point me in the right direction. I think the problem is my code is different to what is in the tutorials so I'm not sure what goes where.
import javax.swing.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.BoxLayout;
class Window extends JFrame implements ActionListener
{
JPanel panel = new JPanel();
JTextField input = new JTextField(10);
JButton but1 = new JButton ("Convert");
JLabel label = new JLabel();
JTextArea output = new JTextArea(1, 20);
public static void main(String[] args)
{
Window gui = new Window();
String[] days = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
}
public Window()
{
super("Swing Window");
setSize(500, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel.add(input);
but1.addActionListener(this);
add(panel);
panel.add(output);
label.setText ("please enter celsius to be converted to Fahrenheit");
panel.add(but1);
panel.add(label);
setVisible(true);
}
public void actionPerformed(ActionEvent event)
{
String inputStr = input.getText();
inputStr = inputStr.trim();
double input = Double.parseDouble(inputStr);
double fahrenheit = input * 1.8 + 32;
if (event.getSource() == but1)
{
output.setText("Here is degrees celsius " + input + " converted `to Fahrenheit: " + fahrenheit);`
}
}
}
There is the executable code.

I skimmed your code, but did not execute it. As others already mentioned in the comments, it is helpful for you to describe what the program does and to describe what you expect/want it to do. Otherwise we are just guessing as to what is wrong and what would be correct.
From my reading of your code, I think you see nothing displayed. Correction: you did call add(); as indicated in one of your more recent comments Here are some notes/explanations:
Your method addComponentsToPane() is never called, thus you never create any BoxLayout objects
Recommendation: variable names begin with lowercase, and don't name a variable the same as a class; it easily creates confusion when reading the code. Thus don't name the argument Window.
Your method addComponentsToPane(), if it were called, creates a Layout object and sets it on the component passed to it but does not actually add any components. The name is thus misleading.
A JFrame's content pane has a BorderLayout by default. When components are added without any additional constraints, the BorderLayout chooses to place the components in a certain order (starting with BorderLayout.CENTER). See documentation of the JFrame class where it says the default is BorderLayout.
A JPanel, when created with the default constructor has a FlowLayout by default.
Since your program never changed the panel's layout manager, this is what gives you the left-to-right flow that you observed.
You want to set the panel's layout to a vertical BoxLayout before you add components to it

Related

java GUI multiple buttons output display error?

I am beginner in Java. This is my first project.
The GUI of the code keeps changing every time I run the code.
Sometimes output doesn't even load completely.
This is the code for just initializing a chess board 8X8 jbuttons.
I have put down the images do checkout the hyperlinks below.
Is there any solution that shows the same output every time the code executes?
package chess;
import game.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.*;
public class board{
static JButton [][] spots =new JButton [8][8];
public static void main(String[] args){
board b =new board();
b.initializeboard(spots);
}
public void initializeboard(JButton [][] spots){
JFrame f = new JFrame("CHESS");
f.setVisible(true);
f.setSize(800,800);
GridLayout layout =new GridLayout(8,8,1,1);
f.setLayout(layout);
for(int ver=0;ver<8;ver++){
for(int hor=0;hor<8;hor++){
JButton button = new JButton();
if((ver+hor)%2==0){
button.setBackground(Color.WHITE); }
else{
button.setBackground(new Color(255,205,51)); }
pieces p =new pieces();
spots[ver][hor] = button;
p.setButton(button);
f.add(button);
}
}
} //initialize board
} // close board
Improper Execution
Correct Execution
Incomplete Execution
I am beginner in Java.
First of all, class names SHOULD start with an upper case character. Have you even seen a class in the JDK that does not start with an upper case character? Learn by example from the code in your text book or tutorial.
Is there any solution that shows the same output every time the code executes?
All components should be added to the frame BEFORE the frame is made visible.
When the frame is made visible the layout manager is invoked and the components are given a size/location. If you add components to a visible panel, then you need to invoke revalidate() and repaint() on the panel to make sure the layout manager is invoked.
Must admit I'm not sure why you get this random behaviour. Some components are getting a size/location and other are not even though the layout manager is not invoked.
I would suggest you restructure your code something like:
JPanel chessboard = new JPanel( new GridLayout(8, 8, 1, 1) );
// add buttons to the panel
JFrame frame = new JFrame("CHESS")
frame.add(chessboard, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
Other comments:
Don't set the size of the frame. Using 800 x 800 will not make each button 100 x 100. The frame size also include the title bar and borders, so each button size will be less than you expect.
Instead you can create a variable outside of your loops:
Dimension buttonSize = new Dimension(100, 100)
Then when you create the button you use:
button.setPreferredSize( buttonSize );
Now when pack() method is invoked is will size the frame at the preferred size of all the components added to the frame.
All Swing components should be create on the Event Dispatch Thread (EDT). Read the section from the Swing tutorial How to Make Frames. The FrameDemo.java code shows you one way to structure your class so that the invokeLater(…) method is used to make sure code executes on the EDT.
Don't make your variables static. This indicates incorrect class design. Check out the MenuLook.java example found in How to Use Menus for a slightly different design where your ChessBoard becomes a component created in another class. You can then define your instance variables in that class.

Having trouble giving my JPanel functionality

*This is my first time using GUI, I seem to miss something my eye can't catch. The code looks fine to me however when i submit it to autoLab I get this error, which I cannot figure out where I went wrong.
{"correct":false,"feedback":"(class java.lang.NumberFormatException)
Error while attempting to call static method q2() on input [1]}
The problem question is q5:
Write a public static method named q5 that takes no parameters and returns a JPanel.
The panel will contain 1 JTextField with any number of columns, 1 JButton with any label,
and 1 JLabel. The panel will have functionality such that when a user enters a number into
the text field (we'll call this value x) and presses the button the label will display the
y-value of a parabola in standard form (https://www.desmos.com/calculator/zukjgk9iry)
where a=5.37, b=-6.07, and c=2.0 at the x-value from the text field
Hint: If you store y in the wrapper class Double instead of the primitive double you can
call toString on it to convert it to a string that can be used as the text for the label
Tip: After clicking the button you may have to resize your window to see the result since
the frame will not automatically resize to fit the new text
Do not create any JFrames in your problem set questions. Doing so will crash the
auto-grader since the grading server does not have a screen to display the JFrame.
Instead, only return the required JPanel in the problem set methods and test with a JFrame
in your main method, or other helper methods that are not graded
This is the code I wrote
public static JPanel q5() {
JPanel panel = new JPanel();
JTextField textField = new JTextField(5);
panel.add(textField);
JLabel label = new JLabel("hello!");
panel.add(label);
JButton button = new JButton("Click Me!");
panel.add(button);
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
int x = Integer.parseInt(textField.getText());
double a=5.37*Math.pow(x, 2);
double b=-6.07*x;
double c=2.0;
String answer= ("y = " + a+ b +c);
label.setText(answer);
}
});
return panel;
}
can you explain where I went wrong , thank you.
So, a NumberFormatException can occur when trying to parse a String, when the String does not contain a number. You did not give enough information to be sure, but I am going to presume that it is this line that causes the problem:
int x = Integer.parseInt(textField.getText());
One thing that strikes me as odd, is that you initialize the JTextField with 5 columns:
JTextField textField = new JTextField(5);
Is that what you want? If you wanted to pre-initialize the text field with a value of 5, you would have to do it like this:
JTextField textField = new JTextField("5");

Java JFrame Boundaries

I'm trying to write a code that does the following:
If I click on the String C(JLabel) whose starting position is (100,100), the String moves WITHIN the boundaries of JFrame. The code itself wasn't hard to implement but I'm having issues with setting the (x,y) for JLabel so that any Part of the String "C" doesn't get cut off.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class adfadf extends JFrame{
JLabel text = new JLabel("C");
Container container = getContentPane();
public adfadf(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container.setLayout(null);
MyMouseListener mml = new MyMouseListener();
text.addMouseListener(mml);
text.setLocation(100,100);
text.setSize(30,30);
add(text);
setSize(400,400);
setVisible(true);
}
public static void main(String[] args) {
new adfadf();
}
}
class MyMouseListener extends MouseAdapter{
#Override
public void mouseClicked(MouseEvent e){
JLabel text = (JLabel)e.getSource();
int x = (int)(Math.random()*(400-30));
int y = (int)(Math.random()*(400-30));
text.setLocation(x,y);
}
}
How should I change
int x = (int)(Math.random()*(400-30));
int y = (int)(Math.random()*(400-30));
in order to achieve what I want?
First, understanding that a JFrame is much more complex then it seems
To start with, a JFrame has a JRootPane, that contains the contentPane and JMenuBar and glassPane
This is further complicated by the fact the window's decorations are actually painted WITHIN the visible bounds of the frame, meaning that the visible area available to your content is actually smaller than the frame's size.
You can have a look at How can I set in the midst?, Graphics rendering in title bar and How to get the EXACT middle of a screen, even when re-sized for more details and examples of this.
But how does this help you? Well, now you know that you have a space of less than 400x400 to display your label in, but how much?
The simple solution is to stop using "magic" numbers, and take a look at something which is been used by the frame, the contentPane. The contentPane is managed by the the JFrame (via the JRootPane) so that it sits within the frame decorations, so you could do something more like...
JLabel text = (JLabel)e.getSource();
int width = getContentPane().getSize().width;
int height = getContentPane().getSize().height;
int x = (int)(Math.random()*(width-30));
int y = (int)(Math.random()*(height-30));
text.setLocation(x,y);
The reason for looking at the contentPane in this instance is simply because, that's the container that the label is actually added to.
This is one of the reasons why we suggest you don't use "magic" numbers, but look at the actual known values at the time you need them.

JButton doesn't appear until clicked

For this program, the JButton doesn't seem to show up unless you click the area where the JButton should be; the JFrame starts up blank. The moment you click the button, the respective code runs and the button finally shows up.
How do I get the buttons to show up upon starting the program?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/*
The Amazing BlackJack Advisory Tool by JoshK,HieuV, and AlvinC.
Prepare to be amazed :O
*/
public class BlckJackUI {
//main class, will contain the JFrame of the program, as well as all the buttons.
public static void main(String args[])
{
//Creating the JFrame
JFrame GUI = new JFrame("Blackjack Advisor");
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.setSize(1300, 900);
GUI.setContentPane(new JLabel(new ImageIcon("C:\\Users\\Hieu Vo\\Desktop\\Green Background.png")));
GUI.setVisible(true);
// Because each button needs to run through the Math class.
final Math math = new Math();
// The Ace Button:
ImageIcon Ace = new ImageIcon("/Users/computerscience2/Downloads/Ace.jpg");
JButton ace = new JButton(Ace);
ace.setSize(300, 100);
ace.setLocation(100, 100);
ace.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//Automatically default the the Ace to 11, and if Bust, Ace becomes 1.
if (math.array.playerhandtotal <= 21)
{
math.cardvalue = math.cardvalue + 11;
}
else
{
math.cardvalue = math.cardvalue + 1;
}
math.array.clicktracker++;
math.calcResult();
JOptionPane.showMessageDialog(null,math.array.result);
}
});
GUI.add(ace);
ImageIcon Two = new ImageIcon("/Users/computerscience2/Downloads/2.jpg");
JButton two = new JButton(Two);
two.setSize(300, 100);
two.setLocation(100, 200);
two.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
/*
This generally repeats throughout the whole class, and the only
thing different is the changing cardvalue. When a button is pressed,
respective cardvalues are added into the playerhand ArrayList, and
totaled up to form playerhandtotal, which is a major factor in
bringing up the advice.
*/
math.cardvalue = math.cardvalue + 2;
math.array.clicktracker++;
math.calcResult();
JOptionPane.showMessageDialog(null,math.array.result);
}
});
GUI.add(two);
Et cetera, Et cetera... Just a bunch of the same stuff, more buttons coded the same exact way as JButton two, but with different value associated to them.
JButton start = new JButton("Start/Reset");
start.setSize(300, 100);
start.setLocation(500,500);
start.addActionListener(new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{
/*
The start button also acts like a reset button, and the concept is fairly
simple. If we reset all the important values to 0 or "null," then the
program acts as if it was just opened.
*/
Arrays array = new Arrays();
array.playerhand.clear();
array.dealer = 0;
math.array.starttracker++;
math.array.clicktracker = 0;
array.playerhandtotal = 0;
math.cardvalue = 0;
array.result = null;
JOptionPane.showMessageDialog(null,"Please select the card \nthat the dealer is showing :)");
}
});
GUI.add(start);
GUI.setLayout(null);
This is all in the same class, and I understand a layout would be nicer, but perhaps there's a way to fix this issue using what I have now?
The program starts blank because you are calling setVisible before you add components. Call setVisible after you add components (in the end of contructor) and it should work fine.
Also, avoid absolute positioning and call of set|Preferred|Minimum|MaximumSize methods for your components. Learn how to use layout managers.
Write GUI.validate(); after you add all the components to your frame. Any time you add something to a frame you have to validate it like this. Otherwise, you will get the behavior that you have described.
No. The problem is caused by the layout. Before adding anything to a JFrame or a JPanel which you want it to have an absolute position, you have to setLayout(null). Otherwise, you'll have unexpected behaviours all the time. I just figured it out by myself after three hours of experimenting; suddenly, I connected your post with other different subject, and it worked, but this isn't well explained on the Internet yet.

JButton alignment in JFrame

I am making a pig latin translater using JFrame in Java. Here's my problem; I have a "quit" button that closes the program; that doesn't matter, but what does is I have no control over its alignment (or any other component). I tried using quit.setAlignmentY(BOTTOM_ALIGNMENT); in the hopes that that would align it to the bottom of the page, but nothing changed. Some help here, please?
In case anyone needs it, here's the code;
public class Main extends JFrame{
private static JLabel label, result;
private static JTextField english;
private static JButton quit;
private static String originalResult = "Translated to pig latin: ";
private static ArrayList<String> beginningSymbols = new ArrayList<>();
private static ArrayList<String> endingSymbols = new ArrayList<>();
//prompt for string to translate, display final result
public Main(){
super("Pig Latin Translator");
setLayout(new FlowLayout());
setVisible(true);
setSize(600, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
translatingHandler th = new translatingHandler();
label = new JLabel("Enter a phrase to translate into pig latin, then press enter:");
english = new JTextField(15);
result = new JLabel(originalResult);
quit = new JButton("Quit program");
english.addActionListener(th);
quit.addActionListener(th);
quit.setAlignmentY(BOTTOM_ALIGNMENT);
add(label);
add(english);
add(quit);
add(result);
english.requestFocus();
}
public static void main(String[] args){
new Main();
}
...
}
The JButton quit is the one I'm trying to align to the bottom of the page. Thanks!
Actually you are using FlowLayout. If you take a look at FlowLayout tutorials it is mentioned that
The FlowLayout class puts components in a row, sized at their
preferred size. If the horizontal space in the container is too small
to put all the components in one row, the FlowLayout class uses
multiple rows. If the container is wider than necessary for a row of
components, the row is, by default, centered horizontally within the
container.
If you insist on using FlowLayout align your components.
Anyways take a look at Using Layout Managers. For your task appropriate layout managers will be BorderLayout.
But if you need something very flexible use GridBagLayout or MigLayout but they are a little complex to use.
So as #HovercraftFullOfEels suggested try avoiding them.
Welcome to the confusing world of Java Swing. You probably want to look into layout managers. Specifically, BorderLayout might be of interest.

Categories

Resources