Close Gps on BoxLayout - java

I have created a setup of buttons using Box.
The problem is there are gaps between all the buttons.
Below is an MCVE version of my code. What I want to achieve is that the buttons "ONE" and "TWO" are touching side by side, with no gap, and buttons "ONE and "ONE" are touching top to bottom with no gap, and for this to continue throughout the setup.
I have read about glue and have tried to use it, but I have not been able to work it out. I am not able to use another layout other than Box as it will not fit in with the rest of my project.
public class Customers {
public static JFrame frame = new JFrame();
public static void frameGui(JPanel panel, String name){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setSize(1200,500);
frame.setVisible(true);
}
public static void ScrollCustomersGui(){
Box box = Box.createVerticalBox();
box.add(customersTableHeadings(box));
box.add(customersTableHeadings(box));
box.add(customersTableHeadings(box));
box.add(customersTableHeadings(box));
JScrollPane scroll = new JScrollPane(box);
JPanel All = new JPanel(new BorderLayout());
All.add(scroll);
frameGui(All, "Customers");
}
public static JPanel customersTableHeadings(Box panel){
Font font = new Font("Courier", Font.BOLD,12);
JPanel customersTable = new JPanel();
JButton custid = new JButton("ONE");
JButton surname = new JButton("TWO");
customersTable.add(custid);
customersTable.add(surname);
return customersTable;
}
}

BoxLayout is designed to distribute unused space among components; struts, glue and filler won't change this. You can use the approach suggested here and here to alter the preferred size of the enclosing scroll pane. More generally, you can implement the scrollable interface. In addition, Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/** #se https://stackoverflow.com/a/26829171/230513 */
public class Customers {
private static final int N = 16;
private void display() {
Box box = Box.createVerticalBox();
for (int i = 0; i < N; i++) {
box.add(customersTableHeadings());
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(box) {
int w = box.getPreferredSize().width;
int h = box.getPreferredSize().height;
#Override
public Dimension getPreferredSize() {
return new Dimension(9 * w / 8, h / 3);
}
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JPanel customersTableHeadings() {
JPanel customersTable = new JPanel();
JButton custid = new JButton("ONE");
JButton surname = new JButton("TWO");
customersTable.add(custid);
customersTable.add(surname);
return customersTable;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new Customers().display();
});
}
}

I found the answer myself. By adding the horizontal and vertical inside the same loop, and by enclosing this in a JApplet it closes the gap.
Below is a full working version of the code:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class Box1 extends JApplet {
public void init() {
Box bv = Box.createVerticalBox();
box(bv);
JScrollPane scroll = new JScrollPane(bv);
JPanel All = new JPanel(new BorderLayout());
All.add(scroll);
Container cp = getContentPane();
cp.add(All);
}
public static void main(String[] args) {
frameGui(new Box1(), "Customers");
}
public static void frameGui (JApplet applet, String name) {
JFrame frame = new JFrame();
frame.getContentPane().removeAll();
frame.setTitle(name);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(applet);
frame.setSize(1200, 500);
applet.init();
applet.start();
frame.setVisible(true);
}
public static Box box(Box boxvert){
for (int i = 0; i < 50; i++){
JTextField one = new JTextField("ONE");
one.setMaximumSize(new Dimension (150,20));
JTextField two = new JTextField("TWO");
two.setMaximumSize(new Dimension (150,20));
Box horizontalBox = Box.createHorizontalBox();
horizontalBox.add(one);
horizontalBox.add(two);
boxvert.add(horizontalBox);
}
return boxvert;
}
}

Related

How to change JButton size in JPanel which is "spread" at whole JFrame

So I have a problem,because mine JButtons are just too bige, I need to change their size to be for eg small rectangles or squares. Right now they look like piano keys.
This is my paste.Could you guys help? :)
I tried SetSize or SetDimension or all the methods available but it did not work out. And I haven't found relevant topic here at overflow. What do you think?
package sg;
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SG extends JFrame {
JPanel pn1;
JPanel pn2;
JPanel pn3;
JPanel pn4;
JButton[] buttony = new JButton[12];
JButton start;
SG() {
super();
setSize(1000, 900);
setResizable(false);
pn1 = new JPanel();
pn2 = new JPanel();
pn1.setLayout(new GridBagLayout());
pn2.setLayout(new GridLayout(2,6));
start = new JButton("Start");
start.addActionListener(new B1());
pn1.add(start);
for (int i = 0; i < 12; i++) {
buttony[i] = new JButton(Integer.toString(i + 1));
buttony[i].setSize(10, 10);
pn2.add(buttony[i]);
}
add(pn1,BorderLayout.NORTH);
add(pn2,BorderLayout.CENTER);
}
public static void main(String[] args) {
SG adam = new SG();
adam.setVisible(true);
}
private class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
Random s = new Random();
int a = s.nextInt(5);
System.out.println(a);
}
}
}
Add pn2 to another JPanel and then set that panel to the JFrame using setContentPane.
The complete code is as follows:
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SG extends JFrame {
JPanel pn1;
JPanel pn2;
JPanel pn3;
JPanel pn4;
JButton[] buttony = new JButton[12];
JButton start;
SG() {
super();
setSize(1000, 900);
setResizable(false);
pn1 = new JPanel();
pn2 = new JPanel();
JPanel contentPane = new JPanel();
pn1.setLayout(new GridBagLayout());
pn2.setLayout(new GridLayout(2, 6));
start = new JButton("Start");
start.addActionListener(new B1());
pn1.add(start);
for (int i = 0; i < 12; i++) {
buttony[i] = new JButton(Integer.toString(i + 1));
buttony[i].setSize(10, 10);
pn2.add(buttony[i]);
}
contentPane.add(pn2);
setContentPane(contentPane);
add(pn1, BorderLayout.NORTH);
add(pn2, BorderLayout.CENTER);
}
public static void main(String[] args) {
SG adam = new SG();
adam.setVisible(true);
}
private class B1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
Random s = new Random();
int a = s.nextInt(5);
System.out.println(a);
}
}
}
If you want to use GridBagLayout, be sure to read this page:
https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
which suggests defining constraints before adding elements.
My choice is MigLayout. Google it and check 5+ versions.
The default size of a component, is barely defined by setSize(), because layout managers often use it to define the dimensions of each components to resize them, so your effort will almost always be overwritten. If you want, try setPreferedSize(), setMinimumSize() and setMaximumSize().
About the topic of Swing, StackOverFlow has plenty of questions related. Try searching tag swing. Also, the Oracle guide is a must-read: https://docs.oracle.com/javase/tutorial/uiswing/TOC.html. And each layout manager has its own documentation. Like Miglayout. http://www.miglayout.com/
Be patient. Several month of time is required to get an rough idea of all this.
GUI components such as JButton need to be placed in a container. JPanel is a container. Containers have an associated layout manager. The layout manager determines the size and location of the components within the container. The GridLayout divides the container into a grid of equal sized cells and places exactly one component in each cell. In the code you posted, each cell contains exactly one JButton, hence each button has the same size. Explicitly setting the JButton size will not help because GridLayout ignores it.
Therefore you need to use a layout manager that is appropriate for your needs. You want to lay out your JButtons in a grid but have each JButton displayed with its preferred size. An appropriate layout manger for this is GridBagLayout. It lays out the components in a grid but sizes each component according to its preferred size.
The following code is a rewrite of the code you posted, because I felt that starting from scratch would be more beneficial to you than patching the code you posted. In the below code, I am using GridBagLayout to lay out the grid of JButtons.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class SG1 implements ActionListener, Runnable {
private static final int NUMBER_OF_BUTTONS = 12;
private static final String START = "Start";
private JButton[] buttons;
private JFrame frame;
private JTextField textField;
public SG1() {
buttons = new JButton[NUMBER_OF_BUTTONS];
}
#Override // java.awt.event.ActionListener
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
switch (actionCommand) {
case START:
Random s = new Random();
int a = s.nextInt(5);
textField.setText(String.valueOf(a));
break;
default:
JOptionPane.showMessageDialog(frame,
actionCommand,
"Unhandled",
JOptionPane.WARNING_MESSAGE);
}
}
#Override // java.lang.Runnable
public void run() {
createAndShowGui();
}
private void createAndShowGui() {
frame = new JFrame("SG1");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createTextFieldPanel(), BorderLayout.PAGE_START);
frame.add(createButtonsPanel(), BorderLayout.CENTER);
frame.add(createStartButtonPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets.top = 3;
gbc.insets.right = 3;
gbc.insets.left = 3;
gbc.insets.bottom = 3;
for (int i = 0; i < NUMBER_OF_BUTTONS; i++) {
buttons[i] = new JButton(String.format("%02d", (i + 1)));
buttonsPanel.add(buttons[i], gbc);
gbc.gridx++;
if (gbc.gridx > (NUMBER_OF_BUTTONS / 2) - 1) {
gbc.gridx = 0;
gbc.gridy++;
}
}
return buttonsPanel;
}
private JPanel createStartButtonPanel() {
JPanel startButtonPanel = new JPanel();
JButton startButton = new JButton(START);
System.out.println(startButton.getFont());
startButton.addActionListener(this);
startButtonPanel.add(startButton);
return startButtonPanel;
}
private JPanel createTextFieldPanel() {
JPanel textFieldPanel = new JPanel();
textField = new JTextField(10);
textFieldPanel.add(textField);
return textFieldPanel;
}
public static void main(String[] args) {
EventQueue.invokeLater(new SG1());
}
}
I suggest you thoroughly study the above code and if there are parts you don't understand, then search the Internet for explanations. You will find many examples for each part of it.
For learning Swing in general, I recommend the online tutorial Creating a GUI With JFC/Swing. I also recommend the book Core JFC (2nd Edition) by Kim Topley

Dynamically changing the size of JFrame when exposed to different screen resolutions

So for a school project I made a grade book in java. When creating the gui I used hardcoded values in the setBounds() methods. Now this worked when I had a 1024×768 screen resolution it looked alright, but when I got a new laptop and it had a 4k screen it looked super small when I ran the program.
So my question would be is there a way to dynamically change the size of the Jframe and all of the associated objects on the frame so it matches the resolution of the screen?
I know that you can get the screen resolution from this
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
but I do not know what would be the best way to do this.
Taking your approach as example and taking this answer and this tutorial as base, here you have the clues:
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
public class Q1 extends JFrame {
public static void main(String[] args) {
Q1 frame = new Q1();
frame.setSize(300, 300);
frame.setMinimumSize(new Dimension(300, 300));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public Q1() {
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
// This is only called when the user releases the mouse button.
System.out.println("componentResized");
}
});
}
#Override
public void validate() {
resize();
super.validate();
};
private void resize() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
System.out.println(width + "," + height);
}
}
This will print the size of the screen when your resize the frame, so you just need to add an if/else in the resize method to make frame bigger
OUTPUT
1366.0,768.0
1366.0,768.0
componentResized
1366.0,768.0
1366.0,768.0
componentResized
1366.0,768.0
1366.0,768.0
componentResized
A layout manager is an object that implements the LayoutManager
interface* and determines the size and position of the components
within a container. Although components can provide size and alignment
hints, a container's layout manager has the final say on the size and
position of the components within the container.
See the example I found using layout managers.Hope you get some idea.THe original author is here Set a layout manager like BorderLayout and then define more specifically, where your panel should go: like
MainPanel mainPanel = new MainPanel();
JFrame mainFrame = new JFrame();
mainFrame.setLayout(new BorderLayout());
mainFrame.add(mainPanel, BorderLayout.CENTER);
mainFrame.pack();
mainFrame.setVisible(true);
puts the panel into the center area of the frame and lets it grow automatically when resizing the frame.See below example for full usage:
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestLayoutManagers {
private JPanel northFlowLayoutPanel;
private JPanel southBorderLayoutPanel;
private JPanel centerGridBagLayoutPanel;
private JPanel westBoxLayoutPanel;
private JPanel eastGridLayoutPanel;
private final JButton northButton = new JButton("North Button");
private final JButton southButton = new JButton("South Button");
private final JButton centerButton = new JButton("Center Button");
private final JButton eastButton = new JButton("East Button");
private final JButton westButton = new JButton("West Button");
public TestLayoutManagers() {
northFlowLayoutPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
southBorderLayoutPanel = new JPanel(new BorderLayout());
centerGridBagLayoutPanel = new JPanel(new GridBagLayout());
eastGridLayoutPanel = new JPanel(new GridLayout(1, 1));
Box box = Box.createHorizontalBox();
westBoxLayoutPanel = new JPanel();
northFlowLayoutPanel.add(northButton);
northFlowLayoutPanel.setBorder(BorderFactory.createTitledBorder("Flow Layout"));
southBorderLayoutPanel.add(southButton);
southBorderLayoutPanel.setBorder(BorderFactory.createTitledBorder("Border Layout"));
centerGridBagLayoutPanel.add(centerButton);
centerGridBagLayoutPanel.setBorder(BorderFactory.createTitledBorder("GridBag Layout"));
eastGridLayoutPanel.add(eastButton);
eastGridLayoutPanel.setBorder(BorderFactory.createTitledBorder("Grid Layout"));
box.add(westButton);
westBoxLayoutPanel.add(box);
westBoxLayoutPanel.setBorder(BorderFactory.createTitledBorder("Box Layout"));
JFrame frame = new JFrame("Test Layout Managers");
frame.setLayout(new BorderLayout()); // This is the deafault layout
frame.add(northFlowLayoutPanel, BorderLayout.PAGE_START);
frame.add(southBorderLayoutPanel, BorderLayout.PAGE_END);
frame.add(centerGridBagLayoutPanel, BorderLayout.CENTER);
frame.add(eastGridLayoutPanel, BorderLayout.LINE_END);
frame.add(westBoxLayoutPanel, BorderLayout.LINE_START);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TestLayoutManagers testLayoutManagers
= new TestLayoutManagers();
}
});
}
}

Swing Ui multiplying panel ghosting

I've got a probelm with my swing ui lately. Everything works fine,untill i trigger a tooltip from a JButton.After that moving the mouse over the rest of the ui is causing weird artifacts and glitching.
Bugged:
I can't show the whole code because its too much but here im initialising the button :
GridBagConstraints bottompane_gbc = new GridBagConstraints();
toggleTorConnectionButton = new JButton();
toggleTorConnectionButton.setToolTipText("Toggles Tor Connection.");
toggleTorConnectionButton.setIcon(new ImageIcon(ResourceHandler.Menueicon3_1));
toggleTorConnectionButton.setMinimumSize(new Dimension(removeFinishedDownloads.getMinimumSize().width, toggleTorConnectionButton.getIcon().getIconHeight()+5));
toggleTorConnectionButton.addActionListener(); // unimportant
bottompane_gbc.gridy = 1;
bottompane_gbc.fill = GridBagConstraints.BOTH;
bottompane_gbc.insets = new Insets(0,15,10,5);
bottompane.add(ToggleTorConnectionButton,bottompane_gbc);
this.add(bottompane,BorderLayout.PAGE_END);
If anybody needs more information to help me pls feel free to ask.Im kind of desperated. XD
EDIT:
After some tinkering im guessing that the problem is related to swing and my use of it.Currently im using alot of Eventlisteners (is this bad?), that might slow down the awt thread ?
Here is a brief extract from HPROF:
http://www.pastebucket.com/96444
EDIT 2:
I was able to recreate the error in a handy and simple example. When you move over the button,wait for the tooltip and then over the ui.You will see ghosting :(.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
public class Main_frame {
public static void main(String[] args) {
new Main_frame();
}
public Main_frame() {
JFrame frame = new JFrame("LOL");
frame.setFocusable(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(400, 500));
frame.setLocationRelativeTo(null);
Download_window download_window = new Download_window();
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("Download", null, download_window, "Main Download Window.");
for (int i = 0; i < 5; i++) {
JPanel pane = new JPanel();
Dimension dim = new Dimension(370, 60);
pane.setPreferredSize(dim);
pane.setMaximumSize(dim);
pane.setBackground(Color.blue);
pane.setMinimumSize(dim);
download_window.jobpanel.add(pane);
}
download_window.jobpanel.repaint();
download_window.jobpanel.revalidate();
frame.add(tabbedPane);
frame.setVisible(true);
}
public class Download_window extends JPanel {
JPanel jobpanel;
public Download_window() {
this.setLayout(new BorderLayout());
jobpanel = new JPanel();
jobpanel.setLayout(new BoxLayout(jobpanel, BoxLayout.Y_AXIS));
JPanel bottompane = new JPanel();
bottompane.setPreferredSize(new Dimension(385, 40));
JButton toggleTorConnectionButton = new JButton();
toggleTorConnectionButton.setPreferredSize(new Dimension(100, 50));
toggleTorConnectionButton.setToolTipText("Toggles Tor Connection.");
bottompane.add(toggleTorConnectionButton);
this.add(bottompane, BorderLayout.PAGE_END);
JScrollPane jobScrollPane = new JScrollPane(jobpanel);
jobScrollPane.getVerticalScrollBar().setUnitIncrement(16);
this.add(jobScrollPane, BorderLayout.CENTER);
}
}
}
Edit 3: Concerning trashgods ideas, I used the EventDispatchThread, I modified the setter to override the getter for size and i crossed out incompatibility by using trashgods code and it was working fine.... So where is the actual difference?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
public class Main_frame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Main_frame();
}
});
}
public Main_frame() {
JFrame frame = new JFrame("LOL");
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(400, 500));
Download_window download_window = new Download_window();
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("Download", null, download_window, "Main Download Window.");
frame.add(tabbedPane);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class Download_window extends JPanel {
JPanel jobpanel;
public Download_window() {
this.setLayout(new BorderLayout());
jobpanel = new JPanel();
jobpanel.setLayout(new BoxLayout(jobpanel, BoxLayout.Y_AXIS));
for (int i = 0; i < 5; i++) {
JPanel pane = new JPanel(){
#Override
public Dimension getPreferredSize() {
return new Dimension(370, 60);
}
#Override
public Dimension getMaximumSize() {
return new Dimension(370, 60);
}
#Override
public Dimension getMinimumSize() {
return new Dimension(370, 60);
}
};
pane.setBackground(Color.blue);
jobpanel.add(pane);
}
JPanel bottompane = new JPanel(){
#Override
public Dimension getPreferredSize() {
return new Dimension(385, 40);
}
};
JButton toggleTorConnectionButton = new JButton("Button"){
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 30);
}
};
toggleTorConnectionButton.setToolTipText("Toggles Tor Connection.");
bottompane.add(toggleTorConnectionButton);
this.add(bottompane, BorderLayout.PAGE_END);
JScrollPane jobScrollPane = new JScrollPane(jobpanel);
jobScrollPane.getVerticalScrollBar().setUnitIncrement(16);
this.add(jobScrollPane, BorderLayout.CENTER);
}
}
}
Could anyone please verify that strange behavior himself? You just need to copy&paste the code from above in Edit3.
Your code exhibits none of the glitches shown above when run on my platform.
Verify that you have no painting problems e.g. neglecting super.paintComponent() as discussed here.
Verify that you have no driver incompatibilities, as discussed here.
Construct and modify all GUI objects on the event dispatch thread.
Don't use set[Preferred|Maximum|Minimum]Size() when you really mean to override get[Preferred|Maximum|Minimum]Size(), as discussed here. The example below overrides getPreferredSize() on the scroll pane, but you can implement Scrollable, as discussed here.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
/** #see https://stackoverflow.com/a/34319260/230513 */
public class MainFrame {
private static final int H = 64;
public static void main(String[] args) {
EventQueue.invokeLater(() -> new MainFrame());
}
public MainFrame() {
JFrame frame = new JFrame("LOL");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane tabbedPane = new JTabbedPane();
JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
for (int i = 0; i < 8; i++) {
panel.add(new DownloadPanel());
}
JScrollPane jsp = new JScrollPane(panel) {
#Override
public Dimension getPreferredSize() {
return new Dimension(6 * H, 4 * H);
}
};
tabbedPane.addTab("Download", null, jsp, "Main Download Window.");
tabbedPane.addTab("Options", null, null, "Options");
frame.add(tabbedPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static class DownloadPanel extends JPanel {
JPanel jobPanel = new JPanel();
public DownloadPanel() {
this.setLayout(new BorderLayout());
this.setBackground(Color.lightGray);
JProgressBar jpb = new JProgressBar();
jpb.setIndeterminate(true);
this.add(jpb);
JPanel buttonPane = new JPanel();
JButton toggleTorConnectionButton = new JButton("Button");
toggleTorConnectionButton.setToolTipText("Toggles Tor Connection.");
buttonPane.add(toggleTorConnectionButton);
this.add(buttonPane, BorderLayout.WEST);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(4 * H, H);
}
}
}

JScrollPane adding items Horizontally, but I want them added vertically

I am creating a bespoke table that I want to scroll up and down, so I am using JScrollPane.
My problem is that each time I add another row in the table it is adding it to the side of the last one, rather than below the last line, which is where I want it to be. Eg it is adding columns to the table rather than rows.
The number of rows that need to be added is uncertain and depends on how many entries there are in the table.
I know I can use a table but for the purposes of this exercise I want to do it this way.
Below is an MCVE version of my code that demonstrates the problem. I left the colour change in so the fields are more visible:
public class Customers {
public static JFrame frame = new JFrame();
public static void frameGui(JPanel panel, String name){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setSize(1200,500);
frame.setVisible(true);
}
public static void ScrollCustomersGui(){
JPanel Table = new JPanel();
Table.add(customersTableHeadings(Table));
Table.add(customersTableHeadings(Table));
Table.add(customersTableHeadings(Table));
JScrollPane scroll = new JScrollPane(Table);
JPanel All = new JPanel(new BorderLayout());
All.add(scroll);
frameGui(All, "Customers");
}
public static JPanel customersTableHeadings(JPanel panel){
FlowLayout FlowCustTable = (FlowLayout)panel.getLayout();
FlowCustTable.setHgap(0);
JPanel customersTable = new JPanel(FlowCustTable);
JTextField custid = new JTextField("ONE");
custid.setPreferredSize(new Dimension(500, 50));
custid.setBackground(Color.CYAN);
customersTable.add(custid);
return customersTable;
}
}
Use vertical BoxLayout here is the modified code :
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class Customers
{
public static JFrame frame = new JFrame();
public static void frameGui(JPanel panel, String name)
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setSize(1200, 500);
frame.setVisible(true);
}
public static void ScrollCustomersGui()
{
Box box = Box.createVerticalBox();
//JPanel Table = new JPanel();
//Table.setLayout(new BoxLayout(Table, BoxLayout.Y_AXIS));
box.add(customersTableHeadings());
box.add(customersTableHeadings());
box.add(customersTableHeadings());
JScrollPane scroll = new JScrollPane(box);
JPanel All = new JPanel(new BorderLayout());
All.add(scroll);
frameGui(All, "Customers");
}
public static JPanel customersTableHeadings()
{
// FlowLayout FlowCustTable = (FlowLayout) panel.getLayout();
// FlowCustTable.setHgap(0);
JPanel customersTable = new JPanel();
customersTable.setMaximumSize(new Dimension(550, 60));
JTextField custid = new JTextField("ONE");
custid.setPreferredSize(new Dimension(500, 50));
custid.setBackground(Color.CYAN);
customersTable.add(custid);
return customersTable;
}
public static void main(String[] args)
{
ScrollCustomersGui();
}
}
you are using a FlowLayout which will not work for your case you can use a BoxLayout check it here, you can also use a GridBagLayout but it is complex :)

Scrolling to the top JPanel inside a JScrollPane

I know a lot of people asked this question, but i still can't resolve this problem.
I have a JPanel inside a JScrollPane. JPanel contains six panels that are loaded dynamically.
After the panels are loaded the system makes a vertical autoscroll to the middle of the panel.
I have to avoid this, so I tried with this:
panel.scrollRectToVisible(scrollPane.getBounds());
But it doesn't work.
My scrollPane has been created in this way
JScrollPane scrollPane= new JScrollPane();
scrollPane.setBounds(panel.getBounds());
scrollPane.setViewportView(panel);
Can you help me?
panel.scrollRectToVisible(scrollPane.getBounds()); should be panel.scrollRectToVisible(JPanelAddedOnRuntime.getBounds());
rest of code (posted here) coudn't be works,
for better help sooner post an SSCCE, short, runnable, compilable
EDIT
works, again you would need to re_read my above 3rd. point
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class ScrollTesting {
private JPanel panel = new JPanel();
private JScrollPane scrollPane = new JScrollPane(panel);
private Vector<JTextField> fieldsVector = new Vector<JTextField>();
private Dimension preferredSize = new Dimension(400, 40);
private Font font = new Font("Tahoma", 1, 28);
public ScrollTesting() {
panel.setLayout(new GridLayout(100, 1));
for (int i = 0; i < 100; i++) {
fieldsVector.addElement(new JTextField());
fieldsVector.lastElement().setPreferredSize(preferredSize);
fieldsVector.lastElement().setFont(font);
panel.add(fieldsVector.lastElement());
}
JFrame frame = new JFrame();
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scrollPane);
frame.setVisible(true);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JTextField tf = (JTextField) fieldsVector.lastElement();
panel.scrollRectToVisible(tf.getBounds());
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ScrollTesting scrollTesting = new ScrollTesting();
}
});
}
}

Categories

Resources