I am using Left-To-Right (LTR) as default Component Orientation for laying out the swing components in JPanels. Now I need to mirrorize all the components in the panel and display them from Right-To-Left(RTL). This will be used for Arabic Locale.
For example the order of components: "label-textbox-button" must turn the new order: "button-textbox-label" without changing their vertical positions.
setComponentOrientation and applyComponentOrientation methods are not working because the layout managers I used, does not support these methods. These methods are supported by FlowLayout, GridLayout etc. I'm using absolute coordinates like this :
JPanel panel = new JPanel();
panel.setBounds(0, 50, 800, 100);
JButton button1 = new JButton("Cancel");
button1.setBounds(100, 60, 100, 120);
panel.add(button1);
when mirrorize, bounds of button will be : (600, 60, 100, 120);
Here is a clear sample about what I want but that is JavaFX version of it. I also do not want to recreate components screens. I just want to repaint and redisplay them according to Locale. So looking for any Java API or open library, if there are any. Thanks for your suggestions and help about where to find it if possible.
Related
I have just finished a project and ran into a problem I could not find anywhere on the internet so far.
I have several JTextFields on a JPanel on a JFrame. When I open the frame, all text fields are in the right place. If I minimize the frame and open it again, all text fields are moved and smaller.
These are photos of my frame before and after I minimize it.
Before:
After:
panel = new JPanel();
panel.setBounds(0, 0, 400, 175);
panel.setVisible(true);
frame.add(panel);
field0 = new JTextField();
field0.setBounds(10, 55, 120, 20);
field0.setVisible(true);
Frame.panel.add(field0);
field1 = new JTextField();
field1.setBounds(250, 55, 125, 20);
field1.setVisible(true);
Frame.panel.add(field1);
field2 = new JTextField();
field2.setBounds(10, 105, 365, 20);
field2.setVisible(true);
Frame.panel.add(field2);
Swing was designed to be used with layout managers. The job of the layout manager is to set the "size" and "location" of each components based on the preferred size of each component and the rules of the layout manager.
In your code the setBounds(...) code is only temporary. When the frame is resized, the layout manager is invoked and the proper size/location is assigned to all components.
So the solution is to not attempt to set the bounds manually but to use layout managers effectively.
Read the section from the Swing tutorial on Layout Managers for more information and working examples to get you started.
Based on your example picture I would suggest you can use the GridBagLayout. It will allow you to create a GUI using row and columns. You can also have components span several columns. I see the you have 5 rows and 3 columns. Download the working demo code from the tutorial and modify it for your requirements.
all text fields are moved and smaller.
Each Swing component should determine its own preferred size.
When you use:
field0 = new JTextField();
the preferred size is what you see.
The better way to create the text field is to use:
field0 = new JTextField(10);
Now the "10" will allow the text field to determines its preferred size to hold 10 "W" characters.
Also, Swing components are visible by default, so you need need to use setVisible(true) for every component.
I am trying to create a JPanel with 3 text fields. Everything else including buttons is falling into place except for textArea3. The final panel is something like this. As you can see in picture, textArea3 uses entire JFrame instead of following setBounds method.
//Text Area 1
JTextArea textArea = new JTextArea();
JScrollPane jScrollPane1 = new JScrollPane(textArea);
jScrollPane1.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
textArea.setFont(new Font("Consolas", Font.LAYOUT_LEFT_TO_RIGHT, 20));
JTextArea textArea2 = new JTextArea();
JScrollPane jScrollPane2 = new JScrollPane(textArea2);
jScrollPane2.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
textArea2.setWrapStyleWord(true);
textArea2.setLineWrap(true);
textArea2.setFont(new Font("Consolas", Font.LAYOUT_LEFT_TO_RIGHT, 20));
//Text Area 3
JTextField textArea3 = new JTextField();
textArea3.setFont(new Font("Consolas", Font.LAYOUT_LEFT_TO_RIGHT, 20));
jScrollPane1.setBounds(30,30,300,300);
jScrollPane2.setBounds(30,400,200,200);
//textArea3 is not working
textArea3.setBounds(600,800,100,50);
button2.setBounds(350,30,80,30);
button1.setBounds(350,400,80,30);
frame.add(button1);
frame.add(button2);
frame.add(jScrollPane2);
frame.add(jScrollPane1);
frame.add(textArea3);
frame.setVisible(true);
EDIT: So this was a bug within the JDK probably. I made another class called class frame and set methods to produce text area etc.
As you can see in picture, textArea3 uses entire JFrame instead of following setBounds method.
No I can't see. I see 5 components. I don't see any component that uses the entire frame.
If in fact you do see the text area take up the whole frame that is because:
the default layout manager for a JFrame is the BorderLayout
when you add components to a BorderLayout and don't specify a constraint, the CENTER is assumed.
however only a single component can be displayed in the CENTER so the layout manager will only give a size/location to the last component added, which happens to be textArea3.
The other components only happen to appear because you manually set the bounds of each component.
You should NOT be attempting to set the bounds of a component. It is the job of the layout manager to set the size and location of each component.
So the solution is to get rid of all the setBounds() statement and use layout managers.
Read the section from the Swing tutorial on Layout Managers for more information. It appears you are tying to use a grid so you can probably use a GridBagLayout.
Also when you create a JTextArea you should use something like:
JTextArea textArea = new JTextArea(15, 20);
This will allow the text area to calculate its size so that 15 rows will display with about 20 characters in each row. The size will be calculated based on the Font used.
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?
Hi i am trying to make java desktop application where i am having 4 jbutton i want to set them bottom left corner one by one i am using null layout for setting them but i dont want to use null layout so
how can i achieve this ?
Thanks in advance
ok = new JButton(s);
ok.setBounds(800, 725, 100, 40);
ok.setBackground(Color.red);
ok.setOpaque(true);
ok.setForeground(Color.BLACK);
c.add(ok);
print = new JButton("Print");
print.setBounds(925, 725, 100, 40);
print.setBackground(Color.red);
print.setOpaque(true);
print.setForeground(Color.BLACK);
c.add(print);
next = new JButton("next");
next.setBounds(400, 725, 100, 40);
next.setBackground(Color.red);
next.setOpaque(true);
next.setForeground(Color.BLACK);
c.add(next);
home = new JButton("home");
home.setBounds(500, 725, 100, 40);
home.setForeground(Color.BLACK);
home.setBackground(Color.red);
home.setOpaque(true);
c.add(home);
Sort answer, use a layout manager.
Long answer, pixel perfect layouts are an illusion in modern user interface design. You can't possible predict the combination of hardware and software that is used to render content to the screen and what effect that will have on your components.
Each system could be using different fonts, rendering pipelines, DPI, hardware...and much more, all of which will change the size of the text and other elements on your UI.
Swing was designed to work around the use of layout managers, trying to do with out greatly increases your work load, as you now need to do the work that the layer manager was as well as be able to detect changes that occur around you and the parent components that you've been added to...
Looking at your code, I could suggest FlowLayout or GridBagLayout as a possible starting point
As #MadProgrammer said you really should use layout managers.
But if you insist on working like this use:
c.setLayout(null);
Coming from Windows Forms (.net), I'm tempted to write the following code:
JFrame frame = new JFrame();
frame.setSize(new Dimension(300, 200));
frame.setVisible(true);
JList list = new JList();
list.setLocation(new Point(50, 50));
list.setSize(new Dimension(100, 100));
list.setVisible(true);
frame.add(list);
JButton button = new JButton();
button.setLocation(new Point(0, 0));
button.setSize(new Dimension(50, 50));
button.setText("myButton");
button.setVisible(true);
frame.add(button);
That should create a window (frame) with a 300x200 size and a list and a button at (50,50) and (0, 0).
Yet when I run the code, all I see is a button (covering the whole area). I guess this must have some special layout system, but I'd like to know how to just put the controls in the specified (x,y) locations with the specified (w,h) dimensions.
Thanks
You need to use Layout Managers:
http://download.oracle.com/javase/tutorial/uiswing/layout/using.html
Although you might be tempted to manually specify a location and size, I would recommend against this unless absolutely necessary. It might seem like learning to use a layout manager is a waste, but the investment will be worth it in the long run.
Using Swing, if you don't specify any layout manager to a top-level container, BorderLayout is used. This layout manager gives you the result you have.
If you want to use absolute positioning, you have to disable the default layout manager first:
frame.setLayout(null);
Then, you can place your components.
What you would be looking for here is a null layout manager.
If you are looking to specify the exact size and location of the objects, then you can use your approach from above.
Take a look at this article
http://www.tech-recipes.com/rx/1205/java-null-layout-manager-swing/
The author, has the same type of example as you, the major difference is the addition of the line
getContentPane().setLayout(null);
In your current implementation you have the default layout, so you would just be layering the list and button on top of each other.
You need absolute positioning. Just set the container's layout manager to null by calling setLayout(null).
Here is the link:
http://download.oracle.com/javase/tutorial/uiswing/layout/none.html