I have:
public class BaseStationFrame1 extends JFrame
{
JButton activateButton;
JButton deactivateButton;
BaseStation bs;
JTextField networkIdField;
JTextField portField;
public BaseStationFrame1(BaseStation _bs){
bs = _bs;
setTitle("Base Station");
setSize(600,500);
setLocation(100,200);
setVisible(true);
activateButton = new JButton("Activate");
deactivateButton = new JButton("Deactivate");
Container content = this.getContentPane();
content.setBackground(Color.white);
content.setLayout(new FlowLayout());
content.add(activateButton);
content.add(deactivateButton);
networkIdField = new JTextField("networkId : "+ bs.getNetworkId());
networkIdField.setEditable(false);
content.add(networkIdField);
portField = new JTextField("portId : "+ bs.getPort());
portField.setEditable(false);
content.add(portField);}
}
My problem is that i don't want the two TextFields to appear on the right of Activate and Deactivate buttons but below them. How can i fix that?
Specify your layout manager, like this:
content.setLayout(new GridLayout(2,2));
That would use the Grid Layout Manager to establish a grid with 2 columns and 2 rows, that your components would then be placed in.
The layout manager you are currently using, FlowLayout, only adds contents onto the end of the current row. it will wrap around once it reaches the constrained edge of the pane, though.
You should also check the other layout managers here
You could alternatively use GridBagLayout , but you will have to specify a GridBagConstraints object you then add alongside the individual elements, like so:
content.add(networkIdField, gridConstraints);
see more on that in the linked tutorial.
can I suggest that you use a Null Layout for the parent component?
setLayout(null);
then use a setBounds(xPos,yPos, Width, Height);
to position the components on the panel etc?
Doing this will prevent Java's UI Manager to manage the components to the Frame, Panel etc.
That seems to be the easiest and less painful way.
Regards
Related
I'm trying to fix the height of the "amountField" text field, but I can't.
I would like the height of amountField to have the same height as the JComboBox that it's above, so it looks better.
Right now, the JTextField looks very tall compared with the rest of design.
I've tried everything that I've read in this forum, but nothing seems to work.
I don't know if it's relevant, but this whole JPanel (WithdrawalScreen) is inside another JPanel with BorderLayout. This panel is the center part of it
Thanks
PictureHere
public class WithdrawalScreen extends JPanel {
Public JPanel init() {
this.setLayout(new GridLayout(0,1));
account = new JLabel("account");
accountSelect = new JComboBox(labels);
amount = new JLabel("amount");
amountField = new JTextField("");
submit = new JButton("SUBMIT");
this.add(account);
this.add(accountSelect);
this.add(amount);
this.add(amountField);
this.add(submit);
return this;
}
}
Try creating the Grid Layout with 5 rows and 1 column. I think the height is messed up because you are not setting the constructor arguments properly.
new GridLayout(5,1);
Grid layout will stretch the component and give the same size to all of its components. In order to keep the "default" size of each component, you can use BoxLayout with BoxLayout.Y_AXIS parameter in its constructor. Another way would be to use a dummy-nested JPanel with another layout. Let's say FlowLayout.
JTextField textField = new JTextField(10);
JPanel nestedPanel = new JPanel(new FlowLayout());
nestedPanel.add(textField);
gridLayoutPanel.add(nestedPanel);
JTextField will not be stretched. nestedPanel will be. Do some experiments yourself and you will find the way that fits your needs.
A link that will help you: A visoual guide to Layout Managers.
I have multiple JTextAreas inside a JPanel. I am using a BoxLayout to make them align vertically and fill the width of the container.
It works, but they seem to expand to fill the entire height as well.
What I really want is simple - a text area that wraps text where I can control the width but allow the height to scale dynamically as more lines are added. The above method was just my best attempt at it. If there is a solution that uses a different layout manager, different text component, etc, that works.
minimal verifiable example below:
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(300, 300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel textAreas = new JPanel();
textAreas.setLayout(new BoxLayout(textAreas, BoxLayout.Y_AXIS));
JTextArea area1 = new JTextArea();
area1.append("this is a string");
area1.setLineWrap(true);
area1.setWrapStyleWord(true);
textAreas.add(area1);
JTextArea area2 = new JTextArea("and another that is much longer, so that it wraps to the next line");
area2.setLineWrap(true);
area2.setWrapStyleWord(true);
textAreas.add(area2);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(textAreas);
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
I have done research on this topic on my own, including looking at different layout managers (http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html), and checking other questions on the site, but I haven't had much luck.
TLDR: Can I make it so each element of a layout has a height that scales to its content but a fixed width? If so how?
What I really want is simple - a text area that wraps text where I can control the width but allow the height to scale dynamically as more lines are added.
The BoxLayout respects the maximum size so the text area grows to fill all the space available in the panel. You can override the getMaximumSize() method to return the preferred height by using something like:
JTextArea area1 = new JTextArea()
{
public Dimension getMaximumSize()
{
Dimension d = super.getMaximumSize();
d.height = getPreferredSize().height;
return d;
}
};
It works...
Not really. Make the frame wider and the text will unwrap. Then shrink the frame and the scrollbar will appear. That is the text will not wrap again
What you need to do is force the panel added to the scroll pane to be the same width as the viewport. This will allow wrapping to work properly.
You do this by implementing the Scrollable interface on the panel. Specifically you need to override the getScrollableTracksViewportWidth() method to return true.
Or an easier solution is to use the Scrollable Panel class which allows you to set properties of the panel to control this behaviour.
You can replace a JPanel with the ScrollablePanel:
//JPanel textAreas = new JPanel();
ScrollablePanel textAreas = new ScrollablePanel();
textAreas.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
Edit:
If there is a solution that uses a different layout manager
Without overriding the getMaximumSize() method of the text areas and when using the Scrollable Panel you should be able to use the following layout managers.
The GridBagLayout allows you to specify the "weightx" constraint. This will allow the component to fill all the available space in the panel.
Or if you don't like specifying all the constrains of the GridBagLayout you could use the Relative Layout which support vertical/horizontal layout of components at their preferred size.
You would just need to use the following to force the component to fill the horizontal space:
//textAreas.setLayout(new BoxLayout(textAreas, BoxLayout.Y_AXIS));
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
textAreas.setLayout(rl);
Made it work! Thank you guys! The code follows. I used BoxLayout since I thought it'd be ideal for stacking questions one on top of the other, but now I got issues with the layout... When I stack several questions the question panels start overlapping. Any thoughts?
panels1 = new MultipleChoice[5];
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
for(int i=0; i<4; i++){
panels1[i]= new MultipleChoice();
panels1[i].setAlignmentX(CENTER_ALIGNMENT);
add(panels1[i]);
}
setVisible(true);
I'm working on designing an Online Test applet. A test has multiple choice and true/false questions. To set up a test I created two JPanel classes, one for the multiple choice question and one for the true/false questions. So when a test is created I'll just dynamically add these panels to a JPanel container according to the non-fixed number of questions.
First, how can I dynamically add new panels to a panel? I thought about declaring an array of the JPanel type. I created and then add objects of this panel class using a for loop:
MultitipleChoicePanel[] PanelArray;
for (...){
PanelArray[i] = new MultipleChoicePanel();
containerpanel.add(PanelArray[i]);
}
I don't know if this is technically possible. This is my first time using Swing, and I tried doing this but obviously it didn't work. Does anyone have an idea how correctly dynamically add these panels?
Second, which of the layout managers is best suited for the container panel in order to fit every new panel added right under the previous one? I thought about dynamically setting up a GridLayout of one column and add rows as I add panels. But I've been really struggling modifying swings dynamically.
Any suggestions?
Thank you so much for your help!
JPanel default layout is FlowLayout and add each component by default to the right so it would fit your problem.
You also may interested in swingx they have HorizontalLayout.
Example:
//in some place
JPanel myBigPanel = new JPanel();
myBigPanel.setLayout(new HorizontalLayout()); // swingx api
List<MultitipleChoicePanel> panelList = new ArrayList<>();
// panelList.add(new MultipleChoicePanel()).. .n times
for(MultipleChoicePanel mp : panelList){
myBigPanel.add(mp);
}
myBigPanel.revalidate(); // revalidate should call repaint but who knows
myBigPanel.repaint();
How to use various Layout Managers
how correctly dynamically add these panels?
After adding components to a visible GUI you need to do:
panel.add(...);
panel.revalidate();
panel.repaint();
"and then add objects of this panel class using a for loop:.....I dont know if its technically possible"
As far as an array of panels, I would do it with an arraylist and do it similarly to how you did it.
import java.util.ArrayList;
ArrayList<MultipleChoicePanel> array = new ArrayList<MultipleChoicePanel>();
for(...){
array.add(new MultipleChoicePanel());
containerPanel.add(array.get(i));
}
import java.awt.*;
import javax.swing.*;
public class JavaSwing extends JApplet {
public void init(){
Container content = getContentPane();
JScrollPane pane= new JScrollPane();
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
panel.add(addPanel("title121"));
panel.add(addPanel("title112"));
panel.add(addPanel("title12"));
panel.add(addPanel("title11"));
pane.getViewport().add(panel);
content.add(pane);
}
public static JPanel addPanel(String title){
JPanel panel = new JPanel();
panel.add(new JButton(title));
return panel;
}
}
I've a big problem with Swing in Java, I used BoxLayout for this but still it looks bad.
Any suggestions about my usage of layouts, or how to change it to look like in assumptions? (here are assumptions)
Container main = new Container();
Container left = new Container();// here goin buttons
Container right = new Container(); // here goin tabs + more buttons, textfields and other stuff
BoxLayout lewyL = new BoxLayout(left, BoxLayout.Y_AXIS);
left.setLayout(lewyL);
left.add(rastrowa); //radiobutton
left.add(wektorowa);//radiobutton
left.add(apDwuliniowa);//checkbox
left.add(wczytaj);//button
left.add(zapisz);//obutton
left.add(wyczysc);//button
BoxLayout prawyL = new BoxLayout(right, BoxLayout.Y_AXIS);
right.setLayout(prawyL);
right.add(zakladki);// tabs (mostly i use BoxLayout but for last one i need something more "complicated")
EDIT: I almost solve this problem, I need to move all elements to left (how it look like)but I have no idea how ;/ Here is constructor of this class.
JLabel label = new JLabel("O wektor");
JLabel labelA = new JLabel("a:");
JLabel labelB = new JLabel("b:");
JButton wykonaj = new JButton("Wykonaj");
JTextField a = new JTextField(5);
JTextField b = new JTextField(5);
add(label);
add(labelA);
add(a);
add(labelB);
add(b);
add(wykonaj);
There's nothing wrong with the way it looks (in my opinion), but if you want it to look a little better, why don't you convert the left panel (which is 6x1) into a 3x2 panel, with the checkboxes/radiobuttons on the left, and buttons on the right? Sounds like a job for GridLayout - one of my favorite classes...
JPanel leftPanel = new JPanel(new GridLayout(3,2));
leftPanel.add(rastrowa); //radiobutton
leftPanel.add(wczytaj); //button
leftPanel.add(wektorowa); //radiobutton
leftPanel.add(zapisz); //obutton
leftPanel.add(apDwuliniowa); //checkbox
leftPanel.add(wyczysc); //button
Note that the 3,2 defines the number of rows,columns. When adding panels, they are added to the grid from left-to-right, and top-to-bottom. GridLayout also auto-sizes the components, so all the buttons etc will be the same width and height, making it look more consistent.
The GridLayout documentation might be useful, and the Visual Guide to Layout Managers is a great place to see other layout managers that might work better for your different situations. I personally find BorderLayout and GridLayout to be the most useful, and cover about 95% of the situations I ever need for my GUIs.
I have this code below to create a page inside of a tab.
I want each layout in one row of the overall box layout but i want the elements to stay in their original size and not expand to fill the width of the overall window. does anyone know what lines of code i need to change or what is the best way of doing this?! The image attached shows what it looks like at the moment
public void createPage4() {
panel4 = new JPanel();
panel4.setLayout(new BoxLayout(panel4, BoxLayout.Y_AXIS));
navigatePanel = new JPanel();
navigatePanel.setLayout(new BoxLayout(navigatePanel, BoxLayout.X_AXIS));
previousButton.setText("Previous");
previousButton.setEnabled(false);
navigatePanel.add(previousButton);
navigatePanel.add(Box.createHorizontalStrut(10));
indexTextField.setHorizontalAlignment(JTextField.CENTER);
navigatePanel.add(indexTextField);
navigatePanel.add(Box.createHorizontalStrut(10));
ofLabel.setText("of");
navigatePanel.add(ofLabel);
navigatePanel.add(Box.createHorizontalStrut(10));
maxTextField.setHorizontalAlignment(JTextField.CENTER);
maxTextField.setEditable(false);
navigatePanel.add(maxTextField);
navigatePanel.add(Box.createHorizontalStrut(10));
nextButton.setText("Next");
nextButton.setEnabled(false);
navigatePanel.add(nextButton);
panel4.add(navigatePanel);
displayPanel = new JPanel();
displayPanel.setLayout(new GridLayout(5, 2, 4, 4));
firstNameLabel.setText("First Name:");
displayPanel.add(firstNameLabel);
displayPanel.add(firstNameTextField);
lastNameLabel.setText("Last Name:");
displayPanel.add(lastNameLabel);
displayPanel.add(lastNameTextField);
panel4.add(displayPanel);
}
image
BoxLayout accepting Min, Max and PreferredSize that came from JComponents
I want each layout in one row of the overall box layout but i want the elements to stay in their original size and not expand to fill the width of the overall window
I'd be to use proper LayoutManager, FlowLayout accepting only PreferredSize, and/or all JComponents layed by GridBagLayout without defininitions of GridBagConstraints stays unchanged on containers resize
doesn't make me sence (my view) for why reason (sure this is your job), but for better help sooner post an SSCCE
The easiest way is to add your panel4 to an other panel that uses GridBagLayout and then add that panel to the container. Then it will be centered and nothing will stretch on resize.
JPanel centeredPanel = new JPanel(new GridBagLayout());
centeredPanel.add(panel4); // add this panel to the container
You should also construct the textfields with a specified number of columns, like
indexTextField = new JTextField(20);