Issue with JPanel as scrollable - java

I am developing a java JApplet to display few 10s of check boxes in scrollable pane. I included these check boxes in JPanel and added this panel on JScrollPane which is added in current ContentPane of applet. Content pane also has few other components like JTextArea, Button and Label. I would see the scroll bar but when I do scrolling, check boxes are scrolled outside of scrollpane and laid over other adjacent components. I tried setPreferredSize() with no success. What could be the issue with scrolling?
My code bites looks like:
public void init(){
contentPane = this.getContentPane();
GridBagLayout grrdbag = new GridBagLayout();
GridBagConstraints components = new GridBagConstraints();
contentPane.setLayout(gridbag);
//button, textarea and label components here
//checkboxes here
components = new GridBagConstraints();
components.anchor = GridBagConstraints.EAST;
contentPane.add(new Label("Data:", Label.RIGHT), components);
components = new GridBagConstraints();
components.gridwidth = GridBagConstraints.REMAINDER;
components.weighty = 1;
components.fill = GridBagConstraints.BOTH;
checkboxesPanel.setLayout(new BoxLayout(checkboxesPanel, BoxLayout.Y_AXIS));
conflictScrollPane = new JScrollPane(checkboxesPanel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
contentPane.add(conflictScrollPane, components);
}
//create check boxes
public void displayboxes(){
checkboxes = new Checkbox[150];
for(int j=0;j<150;j++){
checkboxes[j] = new Checkbox("This is test data for check box here.",null,false);
checkboxesPanel.add(checkboxes[j]);
checkboxesPanel.revalidate();
}
repaint();
validate();
}
//start method
public void start() {
displayboxes();
repaint();
validate();
}

If your example is to believed, you are mixing heavy weight and light weight components. My basic recommendation is, don't. They don't play nice together.
Change your references to Checkbox to JCheckBox instead.
Check out for more info
http://java.sun.com/products/jfc/tsc/articles/mixing/
http://java-antony.blogspot.com.au/2007/07/swing-vs-awt-or-lightweight-vs.html
Shane

Related

JButton in GridBagLayout in a JPanel

I am learning swing from past week, I have some issue with GridBagConstraints to put one button in top left corner but all other buttons in default in GridBagConstraints ?
I am using code that like not original but states the problem
import java.awt.*;
import javax.swing.*;
#SuppressWarnings("serial")
class MyPanel extends JPanel
{
JButton menu = new JButton("Menu"), button = new JButton("Puzzle");
GridBagConstraints gbc1 = new GridBagConstraints(), gbc2 = new GridBagConstraints();
private void setup()
{
gbc1.anchor = GridBagConstraints.FIRST_LINE_START;
gbc2.anchor = GridBagConstraints.CENTER;
gbc2.weightx = 1.0;
gbc2.weighty = 1.0;
}
public MyPanel()
{
this.setLayout(new GridBagLayout());
this.setup();
this.button.setPreferredSize(new Dimension(250, 140));
this.add(menu, gbc1);
this.add(button, gbc2);
}
}
#SuppressWarnings("serial")
public class Test extends JFrame
{
public Test()
{
this.setTitle("Test");
this.setContentPane(new MyPanel());
this.setResizable(false);
this.setSize(800, 600);
this.setVisible(true);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(() -> new Test());
}
}
output
I want menu is top corner.
I read from here but i did not understand this Could you please explain GridBagConstraints for how to do that.
I Hope that problem is clear to understand, if not please let me know in comments.
EDIT:
#camickr suggestion works but a little problem, the Puzzle Button is not in extract center.
Thanks.
By default the GridBagLayout will display all the components centered horizontally and vertically, unless one of the components has a weightx/weighty value not equal to 0. Then that component will fill the extra space in the frame.
So if you want one component at the "top/left" and one in the "center", you need to:
use the "anchor" constraint. It will be different for both components.
the component in the center will need to use the "weightx/weighty" constraints.
However, an easer solution might be to use a combination of panels with different layout managers.
For example:
JPanel menuPanel = new JPanel( new FlowLayout(FlowLayout.LEFT) );
menuPanel.add(menuButton);
JPanel centerPanel = new JPanel( new GridBagLayout() );
centerPanel.add(puzzle, new GridBagConstraints());
frame.add(menuPanel, BorderLayout.PAGE_START);
frame.add(centerPanel, BorderLayout.CENTER);
So now the "top" of the frame will contain a panel with components displayed from the left and the "center" of the frame will contain your puzzle centered in the remaining space of the frame.
Edit:
I solved it but put gridx and gridy to 0 in center component, but i did not completely understand the setttings
Well I mentioned that you would need to use the gridx/gridy constraints. You should always use those constraints as it is very obvious what grid you want to add the component to. The examples from the tutorial always specify those values.
Using gridx/gridy both equal to 0, does not really make sense. The effect is that you have two components trying to share the same grid.
Remove the setResizable(false) statement and shrink the size of the frame to see how the button repositions itself.
It is not normal that two components share the same grid. Normally you would have the menu on the first row and the button on the second row. This will center the button horizontally in the frame and vertically in the space below the menu.
What you are doi

GridBagLayout is not working when I add it to the JFrame

I'm having some issues with my GridBagLayout. I have created a JPanel (in this case it's called mainPanel), whose layout has been set to GridBagLayout. I have specified the constraints for each JButton, and added the constraints to each button. Now, when I run my code, the buttons are always next to each other, irrespective of the gridx/gridy value that I indicate in the constraints. Furthermore, the buttons are always at the center of the JFrame, when I would like one button to appear at the top right, top left, and south.
import javax.swing.*;
import java.awt.*;
public class test {
public static void main (String[] args) {
myJFrame test = new myJFrame();
}
}
class myJFrame extends JFrame {
public myJFrame () {
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel myPanel = new mainPanel();
add(myPanel);
setVisible(true);
}
}
class mainPanel extends JPanel {
public mainPanel(){
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.NORTHWEST;
c.gridx = 1000;
c.gridy= 1;
add(new JButton("1"),c);
c.anchor = GridBagConstraints.NORTHEAST;
c.gridx = 100;
c.gridy= 1;
add(new JButton("2"),c);
c.anchor = GridBagConstraints.SOUTH;
c.gridx = 200;
c.gridy= 1;
add(new JButton("3"),c);
}
}
This is what i get when i run the code
Now, when I run my code, the buttons are always next to each other, irrespective of the gridx/gridy value that I indicate in the constraints.
Correct, you can't just specify random cells. A component must be located in each cell.
Furthermore, the buttons are always at the center of the JFrame,
Yes, this is the default behaviour if you don't specify a weightx/weighty constraint.
Read the section from the Swing tutorial on How to Use GridBagLayout for more information on constraints and working examples.
Why are you picking random x locations like 100, 200, 1000? Maybe a horizontal BoxLayout would be a better layout manager. You can add the components and then add space between them:
panel.add( button1 );
panel.add( Box.createHorizonalStrut(100);
panel.add( button2 );
panel.add( Box.createHorizonalStrut(200);
Or maybe use a FlowLayout and specify the "gap" between each component.

gridheight doesn't affect my buttons

I am new in java applications and I am trying to create a window with 3 buttons in a row at the bottom of the window with extended size. However gridheight doesn't have any affect on my buttons. gridwidth works fine.
Can you give me a feedback on what I am doing wrong? I guess I haven't understand something correctly.
Bellow is my code and the output window.
Thanx in advance!
private JButton button1;
private JButton button2;
private JButton button3;
public SessionTasksPage()
{
JPanel p1=new JPanel(new GridBagLayout());
JPanel p2=new JPanel();
button1 = new JButton("b1");
button2 = new JButton("b2");
button3 = new JButton("b3");
GridBagConstraints gbc =new GridBagConstraints();
//gbc.insets = new Insets(1,1,1,1);
gbc.gridheight = 5;
gbc.gridwidth = 5;
gbc.weightx=15;
gbc.weighty=15;
gbc.fill = GridBagConstraints.BOTH;
p1.add(button2,gbc);
p1.add(button3,gbc);
p1.add(button1,gbc);
add(p1,BorderLayout.SOUTH);
add(p2,BorderLayout.NORTH);
EventHandler1 event1 = new EventHandler1();
button1.addActionListener(event1);
//window terminate setting
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//window size
setSize(600,400);
//pack();
//make window visible
setVisible(true);
//window title
setTitle("HCI-Projet");
//voice command
//new AePlayerWave("bin/sounds/login.wav").start();
}
public class EventHandler1 implements ActionListener
{
public void actionPerformed(ActionEvent event1) {
System.exit(0);
}
}
The problem lies the layout of your main panel. BorderLayout, which you use on that panel, has one large central area (BorderLayout.CENTER), and many smaller areas (such as NORTH and SOUTH). The layout will force anything put anywhere other than CENTER to take up the smallest amount of room possible, and max out the remaining room with what is in the CENTER area (with nothing, in this case). Since you're adding p1 as SOUTH, it keeps the vertical component of p1 as small as it can. If you add p1 as CENTER, it should fix your problem.
As a side note, if all the rows/columns in your grid will have the same height/width, you may find using GridLayout much easier than GridBagLayout.
The problem is the JPanel p1. The space of the panel is created by the standard layout, and if you just use add(p1,BorderLayout.SOUTH);, it won't change.
To make it visible you could use a Border:
p1.setBorder(BorderFactory.createLineBorder(Color.black));
Use a different layout or a GUI builder.

How do I add a footer(with text) to the bottom of this Java application?

Here is a link to a tic-tac-toe game made in Java. All of the code for the GUI version is included in the link.
http://pervasive2.morselli.unimo.it/~nicola/courses/IngegneriaDelSoftware/java/JavaGame_TicTacToe.html
I'm having trouble with adding text relative to the position of other elements. I have tried creating another container but it's not working. I would like to place a footer of text either below the "statusBar" or above it.
Any help would be appreciated.
Here is the relevant code to your problem (next time you should add relevant code to your post instead of just put a link to some other site):
public class TTTGraphics2P extends JFrame {
...
private DrawCanvas canvas; // Drawing canvas (JPanel) for the game board
private JLabel statusBar; // Status Bar
public TTTGraphics2P() {
...
statusBar = new JLabel(" ");
statusBar.setFont(new Font(Font.DIALOG_INPUT, Font.BOLD, 15));
statusBar.setBorder(BorderFactory.createEmptyBorder(2, 5, 4, 5));
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(canvas, BorderLayout.CENTER);
cp.add(statusBar, BorderLayout.PAGE_END); // same as SOUTH
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack(); // pack all the components in this JFrame
setTitle("Tic Tac Toe");
setVisible(true); // show this JFrame
}
...
}
I'm having trouble with adding text relative to the position of other
elements. I have tried creating another container but it's not
working. I would like to place a footer of text either below the
"statusBar" or above it.
Don't know what have you tried but you can follow a Nested Layout approach and wrap two (or many as needed) components into a panel and add this one at content pane's south position. Something like this:
...
statusBar = new JLabel(" ");
JLabel someOtherLabel = new JLabel("Some other label!");
JPanel southPanel = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.weightx = 1;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets = new Insets(8,8,8,8);
southPanel.add(statusBar, constraints);
constraints.gridy = 1;
southPanel.add(someOtherLabel, constraints);
Container cp = getContentPane();
cp.setLayout(new BorderLayout()); // default layout manager is actually BorderLayout
cp.add(canvas, BorderLayout.CENTER);
cp.add(southPanel, BorderLayout.SOUTH);
...
Note: the example makes use of GridBagLayout but might find a more suitable layout manager based on your needs.
Suggested reading
Take a look to Lesson: Laying Out Components Within a Container
Make it programatically into a relativelayout and then with layout params p.addRule(RelativeLayout.ALIGN_BOTTOM, view.getId());....

Swing Components in Different Classes

probably a simple question here working on learning to make a GUI using swing and making mild headway but hit another speed bump. I am trying to keep GUI components grouped in different classes to keep my classes small and allow a more flexible GUI, but I have one component built how do I call it to my main class. Posted below is code to make the frame and the component. I would imagine there is an issue with the way I am calling but am running out of ideas on how else to call it. Any thoughts would be appreciated.....Wasn't very clear with the question trying to add the component to the JFrame in frmMainMenu, issue is that the component doesn't appear in the Frame when run currently
Main Class with JFrame
public class frmMainMenu {
public static void main(String main[]){
//Create Frame
JFrame frmMainMenu = new JFrame();
//Define Layout Manager
GridBagLayout gridBag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
frmMainMenu.setLayout(gridBag);
//Add Components
//Create Left Container
c.fill = GridBagConstraints.VERTICAL;
c.weighty = 1;
c.gridx = 0;
c.gridy = 1;
c.ipadx = 30;
frmMainMenu.add(new comLeftToolBar(),c);
frmMainMenu.setExtendedState(JFrame.MAXIMIZED_BOTH);
frmMainMenu.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//Display Frame
frmMainMenu.setVisible(true);
}
}
Component Code
public class comLeftToolBar extends JPanel{
public comLeftToolBar() {
JPanel comLeftContainer = new JPanel();
GridBagLayout leftGridBag = new GridBagLayout();
comLeftContainer.setLayout(leftGridBag);
GridBagConstraints b = new GridBagConstraints();
JToolBar comLeftToolBar = new JToolBar(JToolBar.VERTICAL);
b.gridx = 0;
b.gridy = 0;
b.ipady = 50;
JButton comNavButton = new JButton();
JButton comProButton = new JButton();
comLeftToolBar.add(comNavButton);
comLeftToolBar.add(comProButton);
comLeftContainer.add(comLeftToolBar,b);
comLeftContainer.setBorder(BorderFactory.createLineBorder(Color.black));
}
}
issue is that the component doesn't appear in the Frame when run currently
Your class is a panel. But then you create another panel (comLeftContainer) and add components to this panel. But you don't add any components to the ComLeftToolBar panel so it remains empty.
For a simple solution, at the bottom of your class you can use:
add( comLeftContainer );
Of course this is not the best solution. This will give you a structure of:
JPanel
JPanel
JToolbar
button
button
There is no need to have such a complicated structure. A toolbar is a component that be added directly to the frame.
If you want to create a class that you can add to the frame then take a look at the Swing tutorial on How to Use Tool Bars for a better structure.

Categories