I've bee teaching myself java and following along with the problems in the book. I'm trying to make a display for my calculator. In the example(I did not attach this) the buttons were a smaller size than what mine are and I can't figure out how to reformat them. I tried using the dimension class but it had no affect. Also, I can't get my text at the top of the calculator to align left.
Here is my code:
public class Calculator extends JFrame {
public Calculator() {
setTitle("Calculator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setSize(300, 300);
setLayout(new BorderLayout());
JPanel numberPanel = new JPanel();
add(numberPanel, BorderLayout.CENTER);
numberPanel.setLayout(new GridLayout(4, 3, 3, 3));
for(int i = 1; i < 10; i++) {
JButton button = new JButton(String.valueOf(i));
numberPanel.add(button);
}
JButton zero = new JButton("" + 0);
JButton dot = new JButton(".");
JButton clear = new JButton("C");
numberPanel.add(zero);
numberPanel.add(dot);
numberPanel.add(clear);
JPanel keyPanel = new JPanel();
add(keyPanel, BorderLayout.EAST);
keyPanel.setLayout(new GridLayout(4, 1, 3, 3));
JButton plus = new JButton("+");
JButton minus = new JButton("-");
JButton times = new JButton("*");
JButton divide = new JButton("/");
keyPanel.add(plus);
keyPanel.add(minus);
keyPanel.add(times);
keyPanel.add(divide);
JPanel equalsPanel = new JPanel();
add(equalsPanel, BorderLayout.SOUTH);
equalsPanel.setLayout(new GridLayout(1, 1));
JButton equals = new JButton("=");
equalsPanel.add(equals);
JPanel textPanel = new JPanel();
add(textPanel, BorderLayout.NORTH);
JTextField inputBox = new JTextField("0.0");
inputBox.setHorizontalAlignment(JTextField.LEFT);
inputBox.setEditable(false);
Font font = new Font("MonoSpaced", Font.BOLD, 20);
inputBox.setFont(font);
textPanel.add(inputBox);
setVisible(true);
}
public static void main(String[] args) {
new Calculator();
}
}
Imports were left off for brevity
GridLayout will laugh at you when you try and set a dimension. It does respect preferred sizes. You should select a layout manager that will respect preferred sizes. Or you can simply pack() (after you add all your components) your frame instead of setSize() and all the components preferred sizes will kick in. (Disclaimer - because of GridLayout though, if you try and resize the frame after that, you components will resize again)
See more at How to use Layout Managers. For a quick view of which layout managers respect preferred sizes and which ones don't, have a look at this post.
A common approach is to nest panels with different layout managers also, as seen here
UPDATE
As mentioned preciously, you should just call pack on the frame instead of set size. With your current code, this would cause the frame to be very small because of the preferred sizes of the components. If you want the buttons to have a bigger preferred size, you can set the font to a bigger font and/or use button.setMargins(new Insets(w,x,y,x)); to make the margins bigger. But it is preferred to pack the frame.
I would recommend using the Window Builder add-on if you’re using Eclipse. This tool will help you with many aspects of Swing. Learn by doing.
WindowBuilder Dowload Link
Related
I am trying to figure out the layout for this(the rest of the code is in the early stages) but for this block, I am trying to figure out the best(and doable) way to format it. I want it to be an 8x8 grid that I will eventually populate with the treasure/empty buttons but I also need a title up top as well as some labels and text on the left. I am unsure if I am able to do multiple grids but what I did below is try to create a 1x2 grid and then place two other grids inside, one with the info on the left(3x2), and another with the 8x8 grid for the buttons. I know it's not close to what it needs to be but none of the grids are showing up at all(it's just putting the title and then one column with 8 rows) and I wanna know if I'm even on any sort of right track, or if I'm just making things up at this point. Any tips would be appreciated, or resources about possibly nesting the grids? I can't find anything in my book about That specifically.
private void buildPanel()
{
// Create labels to display the
treasuresLeftLabel = new JLabel("Treasures left: ");
treasuresFoundLabel = new JLabel("Treasures found: ");
triesLeftLabel = new JLabel("Tries left: ");
// Create text fields for each label
treasuresLeftTextField = new JTextField(2);
treasuresLeftTextField.setEditable(false);
treasuresLeftTextField.setText(String.valueOf(20-game.getTreasuresFound()));
treasuresFoundTextField = new JTextField(2);
treasuresFoundTextField.setEditable(false);
treasuresFoundTextField.setText(String.valueOf(game.getTreasuresFound()));
triesLeftTextField = new JTextField(2);
triesLeftTextField.setEditable(false);
triesLeftTextField.setText(String.valueOf(game.getTriesLeft()));
emptyButton = new EmptyButton();
emptyButton.addActionListener(new emptyButtonListener());
treasureButton = new TreasureButton();
treasureButton.addActionListener(new treasureButtonListener());
// new JPanel object referenced by panel
panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Treasure Hunt"));
// Add a gridlayout to the content pane
panel.setLayout(new GridLayout(1, 2));
panel.setLayout(new GridLayout(3, 2));
panel.add(treasuresLeftLabel);
panel.add(treasuresLeftTextField);
panel.add(treasuresFoundLabel);
panel.add(treasuresFoundTextField);
panel.add(triesLeftLabel);
panel.add(triesLeftTextField);
panel.setLayout(new GridLayout(8, 8));
panel.add(treasureButton);
panel.add(emptyButton);
}
You can't use multiple grids within the same JPanel - one panel, one layout manager.
But you can nest layout managers (and thereby grids) by using nested panels.
For example you could use a BorderLayout for the first panel (containing the title at the top, the info panel on the left and the button panel in the center.
The code to construct those panel then might look like this:
// panel contains the complete UI
panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Treasure Hunt"));
panel.setLayout(new BorderLayout());
panel.add(new JLabel("This is the Title"), BorderLayout.PAGE_START);
JPanel infoPanel = new JPanel();
infoPanel.setLayout(new GridLayout(3, 2));
infoPanel.add(treasuresLeftLabel);
infoPanel.add(treasuresLeftTextField);
infoPanel.add(treasuresFoundLabel);
infoPanel.add(treasuresFoundTextField);
infoPanel.add(triesLeftLabel);
infoPanel.add(triesLeftTextField);
panel.add(infoPanel, BorderLayout.LINE_START);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(8, 8));
buttonPanel.add(treasureButton);
buttonPanel.add(emptyButton);
for (int i = 0; i < 62; i++) {
buttonPanel.add(new JButton(String.format("%02d", i)));
}
panel.add(buttonPanel, BorderLayout.CENTER);
I need to do an assignment and create a calculator. It's a beginner Java course, so keep in mind that I'm no expert. It shouldn't look spectacular, so the easiest way to achieve the below would be great.
The inner workings of it is fine, but drawing it has been a real headache.
We've only gotten exposure to flowlayout so far...and in this instance it's not what I want at all. Let me start of by telling you what layout I'm looking for:
At the top a heading spreading across the calculator, with perhaps a
background fill.
Then below that, 2 buttons next to each other.
Below that, two labels next to each other.
Then two text field next to each other.
Below that, two labels next to each other.
Then two text field next to each other.
I tried drawing it here, but it doesn't format correctly. If I can put it in HTML it would basically be a simple table, with 6 rows and 2 columns. But the top row must span across both columns.
Flowlayout just put everything next to each other from left to right.
After that I tried using GridLayout, but the top heading was the problem here, as it didn't span across both columns.
Here is my code so far:
public class TripCalculator extends JFrame implements ActionListener {
public static final int WIDTH = 400;
public static final int HEIGHT = 300;
public static final int NUMBER_OF_CHAR = 4;
public JTextField stopTime, distance, tripTime, speed;
public TripCalculator() {
setSize(WIDTH, HEIGHT);
WindowDestroyer listener = new WindowDestroyer();
addWindowListener(listener);
Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
JLabel heading = new JLabel("HEADING");
contentPane.add(heading);
contentPane.setLayout(new FlowLayout());
JButton addStop = new JButton("BUTTON1");
addStop.addActionListener(this);
JButton addLeg = new JButton("BUTTON2");
addLeg.addActionListener(this);
contentPane.add(addStop);
contentPane.add(addLeg);
JLabel subHead1 = new JLabel("LABEL1");
contentPane.add(subHead1);
JLabel subHead2 = new JLabel("LABEL2");
contentPane.add(subHead2);
stopTime = new JTextField(NUMBER_OF_CHAR);
contentPane.add(stopTime);
distance = new JTextField(NUMBER_OF_CHAR);
contentPane.add(distance);
JLabel subHead3 = new JLabel("LABEL3");
contentPane.add(subHead3);
JLabel subHead4 = new JLabel("LABEL4");
contentPane.add(subHead4);
tripTime = new JTextField(NUMBER_OF_CHAR);
contentPane.add(tripTime);
speed = new JTextField(NUMBER_OF_CHAR);
contentPane.add(speed);
}
}
I would greatly appreciate if anyone can show me in the right direction.
Flowlayout or Gridlayout by themselves won't help you. Either you can use Gridbaglayout, or a combination of layouts such as FlowLaout+Gridlayout.
If you are drawing a calculator, I am assuming you are drawing something like this :
Where you have title information at the top, a calculator keypad in the middle, and some other buttons at the bottom :
This could be achieved with a vertical box layout, with flowlayouts at the top and bottom, and in the middle a grid layout with all the number keys.
But... without you showing a diagram of what you want its very difficult to say.
Here's an example of using multiple Layout Managers as you can see you can use more than one, but you should use more than one JPanel to achieve what you want.
Also a recommendation is: Don't extend from JFrame, instead create a JFrame object as I did in this example and here's why you shouldn't do that.
import java.awt.*;
import javax.swing.*;
public class LayoutManagersExample {
public static void main(String args[]) {
new LayoutManagersExample();
}
public LayoutManagersExample() {
JFrame frame = new JFrame("Layout Managers Example");
JPanel topPane = new JPanel();
JPanel midPane = new JPanel();
JPanel panesHolder = new JPanel();
JLabel label = new JLabel("Top label");
JTextField field = new JTextField();
field.setColumns(5);
topPane.setLayout(new FlowLayout());
midPane.setLayout(new GridLayout(3, 2));
topPane.add(label);
topPane.add(field);
midPane.add(new JButton("Button 1"));
midPane.add(new JButton("Button 2"));
midPane.add(new JButton("Hello I'm a button"));
midPane.add(new JButton("HEY! Click me :)"));
midPane.add(new JButton("I love you"));
midPane.add(new JButton("This is another button"));
panesHolder.setLayout(new BoxLayout(panesHolder, BoxLayout.Y_AXIS));
panesHolder.add(topPane);
panesHolder.add(midPane);
frame.add(panesHolder);
frame.setSize(400, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
}
}
And this is how it looks like:
I'm trying to add a JLabel to a JPanel to a JFrame. I set the border for the JPanel, but all I see on the JFrame is a small black square in the center of my frame. Whatever I do I can't change the size or location of it. Please help.
Start main = new Start();
Random random = new Random();
JFrame mainFrame = new JFrame("MainFrame");
JPanel mainPanel = new JPanel();
JLabel welcomeLabel = new JLabel();
mainFrame.add(main);
mainFrame.setLayout(new GridBagLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setTitle(names[random.nextInt(names.length)]);
mainFrame.pack();
mainFrame.setVisible(true);
mainFrame.setSize(mainFrameX, mainFrameY);
mainFrame.setResizable(false);
mainFrame.setLocationRelativeTo(null);
mainFrame.add(mainPanel);
mainPanel.add(welcomeLabel);
mainPanel.setBorder(new LineBorder(Color.BLACK));
mainPanel.setSize(new Dimension(200, 200));
welcomeLabel.setFont(new Font("Verdana", 1, 20));
welcomeLabel.setLocation(100, 100);
main.start();
Suggestions:
You will want to read the tutorial, Laying out Components, as it will explain how to code with the Swing layout managers, and this information is essential to solve your current problem.
One caveat: I urge you to avoid the temptation to use the null layout as use of it will lead to creation of code that is very hard to maintain or upgrade.
Your JLabel, welcomeLabel, will of course need some text to be visible.
Don't set it's location via setLocation(...) but again use the layout managers to do the dirty work of placing and sizing your components.
You will also want to call pack() and setVisible(true) on your JFrame after adding all initial components.
Hovercraft is right (+1), make sure you understand how the layout managers are working.
The order in which you do things are important, especially when dealing with the top level containers...
Start main = new Start();
Random random = new Random();
JFrame mainFrame = new JFrame("MainFrame");
JPanel mainPanel = new JPanel();
JLabel welcomeLabel = new JLabel();
welcomeLabel.setFont(new Font("Verdana", 1, 20));
mainPanel.add(welcomeLabel);
mainPanel.setBorder(new LineBorder(Color.BLACK));
// Do this first
mainFrame.setLayout(new GridBagLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setTitle(names[random.nextInt(names.length)]);
// Add your components
mainFrame.add(main);
mainFrame.add(mainPanel);
// Prepare the window for showing, now you have some content.
mainFrame.setResizable(false);
mainFrame.pack();
mainFrame.setVisible(true);
mainFrame.setLocationRelativeTo(null);
main.start();
This will still only produce a small black square in the window, because the JLabel has no content and therefore it's preferred size is going to be (something like) 2x2 (because of the border).
Try adding some text to...
welcomeLabel.setText("Welcome");
And then see the difference
I'm trying to add a JList to a GUI, but am wondering how to position it? I want it to appear on the right hand side of the TextArea for data that will be sent to the GUI for selection.
Can anyone suggest how to do this? Here is the code (note: very new to Java and GUI's)
protected static void createAndShowGUI() {
GUI predict = new GUI();
JFrame frame = new JFrame("Phone V1.0");
frame.setContentPane(predict.createContentPane());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setMinimumSize(new Dimension(300, 400));
frame.setVisible(true); // Otherwise invisible window
}
private JPanel createContentPane() {
JPanel pane = new JPanel();
TextArea = new JTextArea(5, 10);
TextArea.setEditable(false);
TextArea.setLineWrap(true);
TextArea.setWrapStyleWord(true);
TextArea.setWrapStyleWord(true);
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
//Adds the buttons from Top to Bottom
String[] items = {"dsfsdfd"};
list = new JList(items);
JScrollPane scrollingList = new JScrollPane(list);
int orient = list.getLayoutOrientation();
JPanel window = new JPanel();
pane.add(window);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(5, 3));
JButton[] buttons = new JButton[] {
new JButton("Yes"),
new JButton(""),
new JButton("Clr"),
new JButton("1"),
new JButton("2abc"),
new JButton("3def"),
new JButton("4ghi"),
new JButton("5jkl"),
new JButton("6mno"),
new JButton("7pqrs"),
new JButton("8tuv"),
new JButton("9wxyz"),
new JButton("*+"),
new JButton("0_"),
new JButton("^#")
}; // Array Initialiser
for (int i = 0; i < buttons.length; i++) {
buttonPanel.add(buttons[i]);
buttons[i].addActionListener(this);
}
pane.add(TextArea);
pane.add(list);
pane.add(buttonPanel);
return pane;
}
Read the section from the Swing tutorial on Using Layout Mananger. There is no need to only use a single layout manager. You can nest layout managers to get the desired effect.
Wrap your TextArea and list in a new panel with a BorderLayout manager. Basically the BorderLayout manager lets you arrange components using north, south, east, west and center coordinates. The components at the center takes all available space as the parent container has more space available to it.
private JPanel createContentPane() {
JPanel pane = new JPanel(); //this is your main panel
JPanel textAreaPanel = new JPanel(new BorderLayout()); //the wrapper
//Some more code...
//Then at the end
//Make your TextArea take the center
textAreaPanel.add(TextArea, BorderLayout.CENTER);
//And the list to the east
textAreaPanel.add(list, BorderLayout.EAST);
pane.add(textAreaPanel);
pane.add(buttonPanel);
return pane;
}
The cool thing is that you can nest panels inside other panels, adding them different layout managers to get your desired layout.
On an unrelated note, try to follow Java naming conventions. Instead of JTextArea TextArea use JTextArea textArea. It makes it easier for you and people reading your code to understand it.
You could use a layout manager like Mig Layout for that kind of positionning.
(source: miglayout.com)
I could recommend you FormLayout. Before I found this layout I had a real pain with GridBagLayout. FormLayout is more powerful and much more convenient to learn and use and it is free. Give it a chance.
As others suggested, familiarize yourself with the concept of layout managers. There are several that come with the standard Swing API and several good 3rd party ones out there.
In addition, you will want to add the JList to a scroll pane (JScrollPane). You may want to consider adding it to a split pane (JSplitPane). And by consider I don't mean "do it because some guy on the net said so" I mean "do it if it makes sense for your end users".
I had problem using a very simple frame containing two JPanel.
The problem is on the layout of the Center JPanel that contains four JButton.
How can I set a better size for buttons or directly for JPanel that uses the GridLayout. On the picture the problem:
alt http://img42.imageshack.us/img42/4601/horrible.jpg
!
Here the code: ` JFrame window = new JFrame("Horrible! LOL");
JTextField textField = new JTextField("");
textField.setPreferredSize(new Dimension(200,20));
JPanel textPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
textPanel.add(textField);
window.add(textPanel, BorderLayout.NORTH);
JButton plus = new JButton("+");
//plus.setPreferredSize(new Dimension(50,50)); nothing would change
JButton minus = new JButton("-");
JButton per = new JButton("x");
JButton divide = new JButton("/");
JPanel prova = new JPanel(new GridLayout(2,2,10,10));
Dimension d = new Dimension(20,20);
prova.setMaximumSize(d); // nothing changed!
prova.add(plus);
prova.add(minus);
prova.add(per);
prova.add(divide);
window.add(prova, BorderLayout.CENTER);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(250,300);
window.setResizable(false);
window.setVisible(true);`
Which is a good solution?
Kind regards
Unfortunately gridlayout doesent respect preferred sizes. But still if you want to stick to grid layout then you can try something like this:
public static JComponent wrap(JComponent comp)
{
JPanel panel = new JPanel();
panel.add(comp);
return panel;
}
And then instead of direclty adding in to prova add like this:
prova.add(wrap(plus));
prova.add(wrap(minus));
prova.add(wrap(per));
prova.add(wrap(divide));
Tested, Works perfect!!
There are other better ways though
That's what happen to me:
It's definitely attached to the upper edge of the grid.
alt text http://img96.imageshack.us/img96/9431/stillnot.jpg
Even if in this case, in the wrap method I can set the preferredSize of buttons/comp, every buttons is on its own edge. What about others solutions. How would you position buttons for a calculator?
Kind regards and thanx angain!