How to position something on a certain point on a JPanel? - java

Right now I have the following code which adds the JLabel to the top center of the Panel, which I assume is the default
imageLabel = new JLabel();
ImageIcon customer1 = new ImageIcon("src/view/images/crab.png");
imageLabel.setIcon(customer1);
storePanel.add(imageLabel);
imageLabel.setBounds(20, 20, 50, 50);
setBounds obviously isn't putting it at 20,20....so how do you position something to a point within a Panel?

Use the appropriate LayoutManager to place components in the panel.
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
In your case you should be able to use a FlowLayout and set the horizontal and vertical gaps when you create it.
http://docs.oracle.com/javase/7/docs/api/java/awt/FlowLayout.html#FlowLayout(int,%20int,%20int)

Seems your storePanel is JPanel and has default FlowLayout manager, because of your setBounds(20, 20, 50, 50); doesn't work. It will be work with null layout (storePanel.setLayout(null);).
But I recommend you to use LayoutManager.

If you don't mind a bit of manual work you can add constraints to your label using a SpringLayout. This allows you to position edges an exact distance from other edges, which by default also sorts the components size (By basically setting the edges a set distance apart when you lay it out) I have demonstrated below with a textArea, but is could easily apply to your label as well.
public class SO {
public static void main(String[] args) {
//Components
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setSize(frame.getSize());
JTextArea text = new JTextArea();
//Add components
panel.add(text);
frame.add(panel);
//Layout add & setup
SpringLayout layout = new SpringLayout();
panel.setLayout(layout);
layout.putConstraint(SpringLayout.WEST, text, 10, SpringLayout.WEST, panel);
layout.putConstraint(SpringLayout.NORTH, text, 10, SpringLayout.NORTH, panel);
layout.putConstraint(SpringLayout.EAST, text, -10, SpringLayout.EAST, panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
}

Although not recommended, you can do absolute positioning if you set your layout manager to null.
storePanel.setLayout(null);
// imageLabel initialization code
storePanel.add(imageLabel);
imageLabel.setBounds(20, 20, 50, 50);
Oracle Documentation
My advice is to use a Good IDE + UI Builder combo such as:
Netbeans GUI Builder
Eclipse WindowBuilder
IntelliJ GUI Designer
Thease are WYSIWYG tools that can generate Swing code using flexible Layout Managers such as Group Layout or JGoodies Form Layout.
A layout manager is a must if you want to design good UIs. They not only handle the size and positioning of components, but things such as redistributing / repositioning / resizing components on window resize (which is really hard to get right by hand). Also, those UI designers can hint you so that you stick to the guidelines and best practices in order to design high quality / cross-platform UI.

Related

Can I add a rectangle to a Jpanel in java swing and specify constraints for it using GridBagConstraints?

I'm pretty new to GUI and Java as a whole so I hope that I can explain this well enough and understand people's answers.
For a school project, I need to put a bunch of stuff on some rectangles but I'm having issues even adding one rectangle properly.
From researching online, this is what I have (the JPanel and GridBagConstraints are just there to show what I'd like to use):
public class GUI extends JPanel
{
public static void main (String [] args)
{
GUI g = new GUI();
JFrame window = new JFrame("Java Window");
window.setSize(1280, 960);
window.add(g);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel layout = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
}
#Override
public void paintComponent(Graphics g)
{
Color boxColour = new Color(194, 190, 190);
super.paintComponent(g);
g.setColor(boxColour);
g.fillRect(10, 10, 100, 100);
}
}
So right now, the rectangle appears in the window. But how can I add constraints to it? Is that possible? I would think that I should use JPanel to keep everything more organized since there will be many components so I tried adding this:
layout.add(g);
window.add(layout);
window.setVisible(true);
However, the rectangle no longer appeared. What am I doing wrong and how can I fix it and add constraints to my shapes? Thanks!
In your first scenario, the default layout manager of the frame is the BorderLayout and you are adding your "g" panel to the BorderLayout.CENTER. So based on the rules of the BorderLayout your "g" panel will take up all the space available in the frame. So you have plenty of space to paint your rectangle.
However, in your second scenario, your "layout" panel is using the default layout manager of a JPanel which is a FlowLayout which respects the preferred size of any component added to it.
The preferred size of the "g" panel is 10 x 10. So, when you add the "g" panel to the "layout" panel there is nothing to see because all you custom painting is done outside the bounds of the panel.
You need to override the getPreferredSize() method of your GUI panel to return a preferred size of (120, 120) so you can see your rectangle painted with a 10 pixel border around all the edges.
Read the section from the Swing tutorial on Custom Painting for more information and working examples demonstrating how to override the `getPreferredSize() method.
You will also need to read the Swing tutorial on How to Use GridBagLayout for example of using the constraints to add multiple components.

JFrame Layout: Header and 2 Text Areas

I have been trying to code a basic IDE for my programming language but I have not had much experience with JFrames. I am trying to set it up so that the window has a main header and then two text areas below it. I can get the header all sorted out; it's just 3 labels centered in the window. But I cannot get the two text areas to work. I have only tried one so far and I am already seeing loads of stuff wrong. Whenever I resize the window, it doesn't stay beneath the header (which is a Box Layout), but it goes beside it. I also want to make it so that the text areas increase in size when the window changes size. Here is the code that I have so far (this only has one text area).
JFrame frame = new JFrame("DotDotIO");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.setPreferredSize(new Dimension(800,600));
frame.setMinimumSize(new Dimension(600,450));
Box titleText = Box.createHorizontalBox();
JLabel title = new JLabel("<html><span style='color: teal;'>DotDotIO</span></html>");
title.setFont (title.getFont().deriveFont(64.0f));
JLabel version = new JLabel("<html> Version 1.0<br>Created by Luke Carr</html>");
JLabel slogan = new JLabel("<html>Full Potential<br>Minimal Knowledge</html>");
titleText.add(version);
titleText.add(title);
titleText.add(slogan);
titleText.setAlignmentX(frame.getWidth() / 2);
Box inputContent = Box.createHorizontalBox();
JTextArea code = new JTextArea(35,65);
code.setEditable(true);
code.setBorder(null);
inputContent.add(code);
frame.add(titleText);
frame.add(inputContent);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
I currently have it setup so that the text area has a fixed size, but I would like it setup so that the left text area has a width of 65% of the screen, and the right text area takes up 15% of the screen, with 5% margin either side and 5% margin in between both. One final note is that the way my language currently interprets the code is through a file, and then it loops through each line. How would I be able to do this with all of the code typed in the text area on the left?
Currently what I have:
Sorry for asking so many questions. Although I have been doing Java for quite a long time, JFrames have never really come up and I am very new to them.
A box layout doesn't offer much flexibility when it comes to re-sizing the components. This is a link to a similar question. You might want to try a different layout manager.
BoxLayout stretches component to fit parent panel
I would consider using a BorderLayout, and working with Insets of the inner panels. This would give you a full Frame, where you can specify a percentage or fixed pixel amount around the text areas, so no matter what size the window is, the layout adjusts itself to an appropriate distance.
You should probably first put everything into a JPanel and add that to the frame instead of directly adding everything to the frame.
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS))
...
frame.getContentPane().add(mainPanel);
I gave the BoxLayout an alignment of Y_AXIS so that the components will go from top to bottom. But then how do you display two headers side by side? Nest another JPanel inside mainPanel:
JPanel info = new JPanel();
info.setLayout(new FlowLayout(FlowLayout.RIGHT, 50, 10));
JLabel version = new JLabel("<html> Version 1.0<br>Created by Luke Carr</html>");
info.add(version);
JLabel slogan = new JLabel("<html>Full Potential<br>Minimal Knowledge</html>");
info.add(slogan);
mainPanel.add(info);
I set it to a FlowLayout in order to align the JLabels to the right, and so that if the width of the window is too small then Swing will automatically realign them vertically. There are many other ways of doing this, but this is the way I prefer. Aligning the components to the right gives the 65/15 proportions you wanted. If that's not what you wanted, you can change it to FlowLayout.CENTER, FlowLayout.LEFT, etc. The 50 and 10 in the FlowLayout's constructor are the vertical and horizontal spacings between components.
To create the 5% margin on either side of them, I just set the entire mainPanel's border to an empty border that extends for 10 pixels on each side
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
If you just want a border around the version number and the slogan, set info's border the same way.
For your last question: to read the code line by line, use code.getText() and split it using String.split(), as mentioned here.
I rewrote the code and changed some settings:
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Main
{
public static void main(String[] args)
{
JFrame frame = new JFrame("DotDotIO");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel title = new JPanel();
JLabel header = new JLabel("<html><span style='color: teal;'>DotDotIO</span></html>");
header.setFont(header.getFont().deriveFont(64.0F));
title.add(header);
mainPanel.add(title);
mainPanel.add(Box.createVerticalStrut(10));
JPanel info = new JPanel();
info.setLayout(new FlowLayout(FlowLayout.RIGHT, 50, 10));
JLabel version = new JLabel("<html> Version 1.0<br>Created by Luke Carr</html>");
info.add(version);
JLabel slogan = new JLabel("<html>Full Potential<br>Minimal Knowledge</html>");
info.add(slogan);
mainPanel.add(info);
mainPanel.add(Box.createVerticalStrut(20));
JPanel codePanel = new JPanel();
JTextArea code = new JTextArea(25, 65);
codePanel.add(code);
mainPanel.add(codePanel);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setVisible(true);
}
}
If I misunderstood your question, please comment. I hope this helps.
--- EDIT ----------------
The way a FlowLayout works is that it places components in a particular direction until it reaches the edge of the window; then it "hits return" and the components are placed under the first row of components. That is how the two labels were aligned the way they were and are able to align vertically if the screen size is too small.

How to make Components align to the TOP in JPanel with BoxLayout?

I'm developing a game called GalaxyWar, and I am trying to make a map selection menu. I found a problem that when I am using a BoxLayout with BoxLayout.Y_AXIS on a JPanel with setAlignmentX(CENTER_ALIGNMENT), the subcomponents (JPanel's) with assigned size, take up the entire height of the panel (all together), instead of the assigned height!
Here is my code:
scrollPane = new JScrollPane();
scrollPane.setBounds(160, 11, 452, 307);
add(scrollPane);
mapContainer = new JPanel();
mapContainer.setAlignmentX(CENTER_ALIGNMENT);
mapContainer.setAlignmentY(JPanel.TOP_ALIGNMENT);
mapContainer.setLayout(new BoxLayout(mapContainer, BoxLayout.Y_AXIS));
scrollPane.setViewportView(mapContainer);
JPanel demoPanel = new JPanel();
demoPanel.setLayout(null);
demoPanel.setBackground(Color.YELLOW);
demoPanel.setSize(50, 100);
mapContainer.add(demoPanel);
I've researched on this for long, but couldn't find any solutions so far.
try to check out
setPreferredSize()
setMaximumSize()
setMinimumSize()
set all 3 to the same value.
If it still doesn't work, you can try to put the panel, of which you are trying to set the size to fixed, inside another panel.

Java Swing (BoxLayout) alignment issues

I am extremely new to Java Swing, and I'm having quite a bit of issues getting a nice layout going. I have checked out google, and even other answers on this website, but no information I find seems to solve the issue. Here is the result of my efforts:
As you can see, the label, text field, and button are all out of alignment. It is my goal for all of them to have the same left-hand border, and for the button and text field to have the same right-hand border, with these left and right hand borders being each the same distance from the left and righthand sides of my window.
Here are the important parts of my code:
public void run()
{
JFrame frame = new JFrame("Arduino Server");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
InstancePanel = new ServerGUIPanel();
frame.getContentPane().add(InstancePanel);
frame.pack();
frame.setVisible(true);
}
And, in ServerGUIPanel.java:
public ServerGUIPanel()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setPreferredSize(new Dimension(500, 500));
setBorder(new EmptyBorder(10, 10, 10, 10));
StatusLabel = new JLabel("STATUS: BOOTUP");
add(StatusLabel);
PortField = new JTextField();
PortField.setPreferredSize(new Dimension(5000, 20));
PortField.setMaximumSize(PortField.getPreferredSize());
PortField.setActionCommand("PortChanged");
add(PortField);
ConnectionButton = new JButton();
ConnectionButton.setPreferredSize(new Dimension(5000, 20));
ConnectionButton.setMaximumSize(ConnectionButton.getPreferredSize());
ConnectionButton.setActionCommand("ConnectionClicked");
add(ConnectionButton);
}
Does anyone have a simple solution to this? What am I doing wrong here?
Thank you very much!
--Georges Oates Larsen
Read the section from the Swing tutorial on How to Use BoxLayout for the basics of using a BoxLayout as well as a section on alignment issues.
Basically you need to make sure the alignmentX value of all components is set to be left aligned.
Also:
Don't use setPreferredSize() to set the size of a component. Each Swing component will determine its own preferred size.
Use Java naming conventions. Variable names should NOT start with an upper case character.
I would not recommend using setPreferredSize() AND setMaximumSize(). The latter will cause problems when stretching your main frame. [Your components will likely not want resize]
You should be using layout managers to handle all the alignments itself. I would stay away from using BoxLayout in this case, as different components want to size differently, and that will sway the alignment when added into your BoxLayout panel.
Moreover, you might want to give your main frame a layout as well.
Can you post how you used your GridBagLayout?

How to set coordinates for components?

I'm a new user on Swing, and I have problem with drawing components by coordinates. Please, look at this code:
JFrame frame=new JFrame();
frame.setBounds(new Rectangle(0, 0, 700, 600));
frame.getContentPane().setBackground(Color.yellow);
frame.setVisible(true);
JPanel graph=new JPanel();
graph.setBounds(new Rectangle(0, 0, 700, 300));
graph.setBackground(Color.white);
graph.setOpaque(true);
frame.getContentPane().add(graph);
I need that JPanel closes 50% from JFrame, but now it closes 100%, and JFrame has white color for background. How should I fix the mistake? Also, is there any mean for setting width and height using percents? For example, 50% for width. Or may be exists any containers for my question? Thank you
don't use whatever#setBound(), use Standard LayoutManager, in this case is GridLayout(2, 0) best of ways how to do it, your JFrame and its JPanels will be resizable on both directions
If you really want absolute positioning you could try disabling the default layout manager, as shown in Doing Without a Layout Manager. However, most of the time it's best to (depending what your container is intended to show) choose an appropriate layout manager.

Categories

Resources