JTextField size - java

I have a JPanel like this:
GridBagConstraints constPanelInfo = new GridBagConstraints();
panelInfo = new JPanel(new GridBagLayout());
JLabel sensor1 = new JLabel("Sensor: ");
constPanelInfo.gridx = 0;
constPanelInfo.gridy = 0;
constPanelInfo.weightx = 0.0;
constPanelInfo.fill = GridBagConstraints.NONE;
panelInfo.add(sensor1, constPanelInfo);
constPanelInfo.gridx = 1;
constPanelInfo.gridy = 0;
constPanelInfo.weightx = 1.0;
constPanelInfo.fill = GridBagConstraints.HORIZONTAL;
campoSensor.setPreferredSize(new Dimension(100, campoSensor.getPreferredSize().height));
panelInfo.add(campoSensor, constPanelInfo);
where campoSensor is defined as:
private JTextField campoSensor = new JTextField();
...but the JTextField is not scaled to 100 px weight as I want: it stays the same size it had before writting the setPreferredSize method. Any idea here?

Hopefully this is what you're looking for... setting
constPanelInfo.weightx = 0;
for the sensor should keep it at the specified 100px. i.e If all the weights are zero, all the extra space appears between the grids of the cell and the left and right edges.
Remember that if the weigths are set and because of
constPanelInfo.fill = GridBagConstraints.HORIZONTAL;
The campoSensor is going to fill the full width of the cell regardless of the preferred size.
This width will probably be determined by the size of the JFrame that your panel is sitting in.

Try to set constPanelInfo.iPadX=100; instead of setting preferred size.

Related

Java component positioning on GridBagLayout

I am trying to position components on JPanel using GridBagLayout but the output I am getting is completely off from what I expect. Hope to get some clarity with brilliant-minded ppl in stackoverflow:).
Below I have provided a piece of code and screentshot of the program. My questions are:
Why the JLabel Choose measure system to convert is not on Y-axis = 1? As to my knowledge, c.gridy=1 is one pixel downward, but the label is stuck on the top leaving no space from the Frame title. And also, why is it positioned so weird, i.e., not really in the center, nor in the start?
Why is there such a big space between ComboBoxes From... and To..., but there is no space between ComboBox To... and TextField Enter value here...?
Here is the code:
JPanel container = new JPanel();
container.setLayout(new GridBagLayout());
getContentPane().add(container, BorderLayout.NORTH);
TitledBorder outputCenter;
GridBagConstraints c = new GridBagConstraints();
label = new JLabel("Choose measure system to convert");
label.setFont(new Font("Times New Roman", Font.PLAIN, 20));
c.gridx = 0;
c.gridy = 1;
container.add(label, c);
fromList = new JComboBox<String>(convertFrom);
c.gridx = 0;
c.gridy = 2;
container.add(fromList, c);
toList = new JComboBox<String>(convertTo);
c.gridx = 1;
c.gridy = 2;
container.add(toList, c);
//Field where user enters the value to be converted
input = new JTextField("Enter value here...");
input.setPreferredSize(new Dimension(150,30));;
input.setEditable(true);
input.setBackground(Color.WHITE);
input.setBorder(BorderFactory.createLineBorder(Color.BLACK));
input.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
input.setText("");}});
c.gridx = 2;
c.gridy = 2;
container.add(input, c);
And here is the screentshot:
EDIT: If I change the code from:
label = new JLabel("Choose measure system to convert");
label.setFont(new Font("Times New Roman", Font.PLAIN, 20));
c.gridx = 0;
c.gridy = 1;
container.add(label, c);
label = new JLabel("Choose measure system to convert");
label.setFont(new Font("Times New Roman", Font.PLAIN, 20));
c.gridx = 1; // changed this line
c.gridy = 1;
container.add(label, c);
The outcome is like this:
This is very confusing me as why changing the position of one component effects everything?
GridBagConstraints sets up the frame into effectively a grid. The width and height of the cells in the grid are determined by the size of the data in the cell by default unless otherwise specified. So if you want to add some space in-between cells I suggest ipadx and ipady. You can also utilize anchor for adjusting your data in the cell. I also suggest weightx and weighty for adjusting the actual cell size.
So imagine something like this as your current set up:
EDIT: Example of what your new GBC looks like. The numbers are (gridx,gridy)
Why the JLabel Choose measure system to convert is not on Y-axis = 1? As to my knowledge, c.gridy=1 is one pixel downward
You're confusing yourself, c.gridy = 1 is not positioning it 1 pixel downward but rather on the next row, but as there's no previous row, then it takes the first row. For reference see: GridBagConstraints#gridy which says the following:
Specifies the cell at the top of the component's display area, where the topmost cell has gridy=0. The value RELATIVE specifies that the component be placed just below the component that was added to the container just before this component was added.
Next question:
And also, why is it positioned so weird, i.e., not really in the center, nor in the start?
It is centered in its own cell, if you want to center it on the JFrame, then you might need to create it on its own gridx = 1 and the rest of components on the other ones (0 and 2) or make it span 2 or more columns based on you want it to look like...
Why is there such a big space between ComboBoxes From... and To..., but there is no space between ComboBox To... and TextField Enter value here...?
It is because your program is giving it all the extra space because of the large text on the first cell...
You can have something like this:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class GridBagLayoutExample {
private JFrame frame;
private JPanel pane;
private JLabel label;
private JTextField field;
private JComboBox<String> box1;
private JComboBox<String> box2;
private GridBagConstraints gbc;
public static void main(String[] args) {
SwingUtilities.invokeLater(new GridBagLayoutExample()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
pane = new JPanel();
pane.setLayout(new GridBagLayout());
gbc = new GridBagConstraints();
label = new JLabel("Choose measure system to convert");
box1 = new JComboBox<>(new String[] {"From..."});
box2 = new JComboBox<>(new String[] {"To..."});
field = new JTextField(10);
gbc.insets = new Insets(5, 5, 5, 5); //We add extra space at top, left, bottom, right of each component
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 3; //We make our text to span 3 cells
pane.add(label, gbc);
gbc.gridy = 1;
gbc.gridwidth = 1; //We return the spanning to 1 single cell
pane.add(box1, gbc);
gbc.gridx = 1;
pane.add(box2, gbc);
gbc.gridx = 2;
pane.add(field, gbc);
frame.add(pane);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Which produces the following output:

Getting the height of JTextPane content

The main idea is to draw a specific form, using Swing library(it will be used to generate an image, which will be transfered to a escpos printer, but thats another question). The form itself has a full width container at the top, which represents the label. The label has a custom font, font size and can have a linewrap, therefor i used JTextPane. JTextPane element, and all of the form, will have a fixed size of 500px.
As a test, the code looks like:
JFrame fr = getFrame();
JPanel root = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JPanel titleP = new JPanel(new BorderLayout());
titleP.setBorder(BorderFactory.createTitledBorder("titleP"));
c.fill = GridBagConstraints.BOTH;
c.gridy = 0;
c.gridx = 0;
c.gridwidth = 8;
c.weightx = 1.0f;
c.weighty = 1.0f;
JTextPane tp = new JTextPane();
JScrollPane sp = new JScrollPane(tp);
Font font = new Font("Arial",Font.BOLD, 37);
tp.setFont(font);
tp.setText("fdsfdsf sdf sdf sd fdsfsdf sdf sd fsd fdsf sdf sdf sdf sdf sdf sdf sdf ds");
tp.setOpaque(false);
titleP.add(sp);
root.add(titleP,c);
JPanel infoP = new JPanel();
infoP.setBorder(BorderFactory.createTitledBorder("infoP"));
c.gridwidth = 5;
c.gridy = 1;
c.gridx = 0;
//infoP.setPreferredSize(new Dimension(350,200));
root.add(infoP,c);
JPanel priceP = new JPanel();
priceP.setBorder(BorderFactory.createTitledBorder("priceP"));
c.gridx = 5;
c.gridwidth = 3;
root.add(priceP,c);
fr.setContentPane(root);
fr.pack();
int size1 = fr.getHeight();
int width = 120;
fr.setSize(width, 0);
size1 += tp.getHeight();
size1 += 25;
fr.setSize(width, size1);
fr.setVisible(true);
The question is, how do i calculate JTextPane's full size, in order to set its height to the container, which is holding it? The part where i hardcodedly try to give out a height correction, even worked, but then i added a font...
I wrote a detailed answer on a similar question. Check here
The idea is that getPreferredSize().height called on a JTextPane will return the height needed to display the current content given the current width. If the width is not set yet, it will return the height needed if the width of the JTP was the width of the longest line.
With the same logic, getPreferredSize().width will return the width of the longest line.
For those who maybe struck on the same problem(or just curious). Found a solution here: link
The idea came to be quite simple:
public int getContentHeight(int width, String content) {
JEditorPane dummyEditorPane = new JEditorPane();
dummyEditorPane.setSize(width, Short.MAX_VALUE);
dummyEditorPane.setText(content);
return dummyEditorPane.getPreferredSize().height;
}

GridBagLayout dividing JPanel

i am trying to divide my JPanel using GBL on 200 rows and 200 columns(one cell for one pixel. Any idea how to do this properly. Code posted below doesn't work for me.
JPanel pane = new JPanel;
pane.setSize(200,200);
GridBagLayout layout = new GridBagLayout();
layout.columnWidths = new int[200]; layout.rowHeights = new int[200];
I would be grateful for any help.
You could use the GridBagConstraints class to set the size of each pixel using the gridwidth and gridheight properties. Then apply these constraints to your GBL using layout.setConstraints(GridBagConstraints instance)
Something like this would do, you would just need to add the part to change the pixels by either reading a list or array:
int y=0;
int x=0;
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
for(int stop=0;stop<=200;stop++){
c.gridx = ++x;
c.gridy = ++y;
pane.add(each_pixel, c);
}

Components in GridBagLayout are put to the center, without taking all free space

I have a GridBagLayout with two components: JRadioButton and JLabel. Text in a label differs by length. This GridbagLayout is added to JPanel. So when I have a lot of components they are not aligned well at the end. Here is what I mean:
-----radio btn-label-----
---radio btn-label --
-------radio btn-lbl-----
But I need the following:
-radio btn-label -
-radio btn-label -
-radio btn-lbl -
This is how my grid looks like for now:
public class MyPanel extends JPanel {
private JLabel info;
private JRadioButton select;
public MyPanel() {
this.achiev = achiev;
achievementInfo = new JLabel();
selectAchiev = new JRadioButton();
setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 0;
constraints.anchor = GridBagConstraints.LINE_START;
add(selectAchiev, constraints);
StringBuilder builder = new StringBuilder();
builder.append("<html><b>").append("some text").append("</b><p>");
builder.append("<i>").append("some more text").append("</i>");
info.setText(builder.toString());
constraints.gridx = 1;
constraints.gridy = 0;
constraints.fill = GridBagConstraints.HORIZONTAL;
add(info, constraints);
}
//--------------
JPanel panel = new JPanel(new BoxLayout(), BoxLayout.YAXIS);
for(int i = 0; i < 10; ++i) {
panel.add(new MyPanel());
}
You're adding 10 panels which all have their own gridbag layout, checkbox and label. So each panel has its own grid, and the width of the cells are computed independantly, based on the components they contain.
If you want a well-aligned single grid, you should have a single panel using GridBagLayout, and add your 10 labels and 10 checkboxes to this unique panel.
Moreover, you should give a weightx > 0 to the label's constraint if you really want it to fill horizontally.
I think you miss the weightx, weighty constraints as it is said in this GrigBadLayout document:
Unless you specify at least one non-zero value for weightx or weighty, all the components clump together in the center of their container. This is because when the weight is 0.0 (the default), the GridBagLayout puts any extra space between its grid of cells and the edges of the container.
If you want to make your components look like that, i refer using BoxLayout
private void init() {
Box outerBox = new Box(BoxLayout.Y_AXIS);
outerBox.add(createLineWithRadioButtonAndLabel());//line 1
outerBox.add(createLineWithRadioButtonAndLabel());//line 2
outerBox.add(createLineWithRadioButtonAndLabel());//line 3
add(outerBox);
}
private Box createLineWithRadioButtonAndLabel() {
Box line = new Box(BoxLayout.X_AXIS);
JRadioButton radio = new JRadioButton("radio button");
JLabel label = new JLabel("some text");
line.add(radio);
line.add(Box.createRigidArea(new Dimension(20, 1)));// add some horizontal space. Here is 20
line.add(label);
line.add(Box.createHorizontalGlue());
return line;
}

size of components in GridBagLayout is not correct

I'm making a simple interface in Java. I want to have on top a JButton with a set size of 200*20 and directly under it a JScrollPane encapsulating a JTextArea. The size of this field should be the remaining width and height of the JPanel in which it is placed (but with a minimum of 640*480) and must resize when making the window larger/smaller (until its minimum size).
I tried making this with a GridBagLayout but this does not seem to be working. Does somebody know how I can fix this?
//Initialize components
Dimension minSize = new Dimension(640, 480);
info = new JTextArea("hello");
info.setEditable(false);
JScrollPane scrollPane = new JScrollPane(info);
scrollPane.setMinimumSize(minSize);
JButton update = new JButton("update");
JPanel jp = new JPanel();
jp.setLayout(new GridBagLayout());
GridBagConstraints grid = new GridBagConstraints();
//add components
grid.fill = GridBagConstraints.NONE;
grid.anchor = GridBagConstraints.NORTHWEST;
grid.gridheight = 1;
grid.gridwidth = 1;
grid.weighty = 1.0;
grid.weightx = 1.0;
grid.gridx = 0;
grid.gridy = 0;
jp.add(update, grid);
grid.fill = GridBagConstraints.BOTH;
grid.gridx = 0;
grid.gridy = 1;
grid.weighty = 15;
grid.gridheight = 15;
grid.gridwidth = 15;
jp.add(scrollPane, grid);
this.add(jp,BorderLayout.NORTH);
This is how it looks now: as I described before this is not what I want; the TextArea needs to fill the entire screen (so it needs to be taller).
How can I do this?
this.add( jp, BorderLayout.CENTER );
As specified in the documentation:
The components are laid out according to their preferred sizes and the
constraints of the container's size. The NORTH and SOUTH components
may be stretched horizontally; the EAST and WEST components may be
stretched vertically; the CENTER component may stretch both
horizontally and vertically to fill any space left over.

Categories