Problem and Code Summary:
This will make sense if you run the code below. I'm using a JScrollPane
and its scroll bar is disappearing when it is placed in a JPanel
with a BorderLayout
(NORTH). When the JPanel
has a BorderLayout
(CENTER), it works fine (with the scroll bar showing up). If you try to remove many of the components with the remove buttons, it gets annoying because the JScrollPane
(with all of its components) clumps up in the middle of the JPanel
it's in, when you want it to stay at the top. I tried to prevent this by obviously changing the BorderLayout
of the JPanel
from CENTER TO NORTH, but that just takes out the scroll bar completely. In the following code, the Main.placement (line 28) (change it to CENTER/NORTH to mess with it) controls the type of layout being used and line 171 shows how it is implemented. I just want to align the JSCrollPane
at the top with the scroll bar showing up when it is neccessary.
Code Summary:
package main;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class Main{
public static final String placement = BorderLayout.CENTER;
public static void main(String[] args){
new TimeChart(true);
}
}
@SuppressWarnings("serial")
class TimeChart extends JFrame {
private boolean admin;
private TimeTable timeTable;
private static final JLabel title;
private final JLabel volLabel;
static {
title = new JLabel("Time Chart ");
}
private class TimeTable extends JPanel {
private JScrollPane scrollPane;
private JPanel table;
public final ArrayList<SessionRow> sessionRows;
private final JButton addButton;
private final JButton applyButton;
private static final double weight_sessnum = 0.2;
private static final double weight_signinout = 1.0;
private static final double weight_time = 0.3;
private static final double weight_delete = 0.0;
public class SessionRow {
private final SessionRow thisSessionRow; // for inner classes
private JTextField sessionnum, signinField, signoutField, total;
private JButton removeButton;
private SessionRow(int y) {
thisSessionRow = this;
String signinstring = "*signin time*";
String signoutstring = "*signout time*";
sessionnum = new JTextField("Session " + y + ": ");
sessionnum.setEditable(false);
signinField = new JTextField(signinstring);
signinField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
signinField.selectAll();
}
@Override
public void focusLost(FocusEvent e) {
}
});
signinField.setEditable(admin);
signoutField = new JTextField(signoutstring);
signoutField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
signoutField.selectAll();
}
@Override
public void focusLost(FocusEvent e) {
}
});
signoutField.setEditable(admin);
String totalstring = null;
try {
totalstring = "*session total*";
} catch (Exception e) {
totalstring = " -- ";
}
total = new JTextField(totalstring);
total.setEditable(false);
removeButton = new JButton("Remove");
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
thisSessionRow.remove();
sessionRows.remove(thisSessionRow);
revalidate();
repaint();
}
});
}
public void remove() {
table.remove(this.sessionnum);
table.remove(this.signinField);
table.remove(this.signoutField);
table.remove(this.total);
table.remove(this.removeButton);
}
}
public TimeTable() {
super();
table = new JPanel();
scrollPane = new JScrollPane(table);
applyButton = new JButton("<html><div style=\"text-align: center;\">Apply<br>Changes</html>");
applyButton.setMargin(new Insets(5, 5, 5, 5));
applyButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
applyAllChanges();
}
});
applyButton.setEnabled(false);
addButton = new JButton("Add");
addButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sessionRows.add(new SessionRow(sessionRows.size() + 1));
setupAll();
revalidate();
repaint();
if (!applyButton.isEnabled())
applyButton.setEnabled(true);
}
});
sessionRows = new ArrayList<SessionRow>();
setupSessionRows();
setupAll();
this.setLayout(new BorderLayout());
this.add(scrollPane, Main.placement); //PAY ATTENTION HERE
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setPreferredSize(new Dimension(30, 0));
bar.setUnitIncrement(10);
InputMap im = bar.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke("down"), "positiveUnitIncrement");
im.put(KeyStroke.getKeyStroke("up"), "negativeUnitIncrement");
scrollPane.setBorder(BorderFactory.createLineBorder(Color.red));
this.setBorder(BorderFactory.createLineBorder(Color.green));
}
public void setupSessionRows() {
sessionRows.clear();
for (int i = 0; i < 30; i++) {
sessionRows.add(new SessionRow(i + 1));
}
System.gc();
}
public void setupAll() {
table.removeAll();
table.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(0, 0, 5, 2);
c.gridx = 0;
c.gridy = 0;
initColumnHeader(c);
for (int y = 0; y < sessionRows.size(); y++) {
c.gridy++;
initSessRow(sessionRows.get(y), c);
}
c.gridy++;
if (admin) {
initNewButtonRow(c);
c.gridy++;
}
initTotalHeader(c);
}
public void initSessRow(SessionRow row, GridBagConstraints c) {
c.weightx = weight_sessnum;
c.gridx = 0;
table.add(row.sessionnum, c);
c.weightx = weight_signinout;
c.gridx = 1;
table.add(row.signinField, c);
c.weightx = weight_signinout;
c.gridx = 2;
table.add(row.signoutField, c);
c.weightx = weight_time;
c.gridx = 3;
table.add(row.total, c);
if (admin) {
c.weightx = weight_delete;
c.gridx = 4;
table.add(row.removeButton, c);
}
}
public void initTotalHeader(GridBagConstraints c) {
c.weightx = weight_sessnum;
c.gridx = 0;
JTextField totalLabel = new JTextField("Total: ");
totalLabel.setEditable(false);
table.add(totalLabel, c);
c.weightx = weight_signinout;
c.gridx = 1;
JTextField blank1 = new JTextField();
blank1.setEditable(false);
table.add(blank1, c);
c.weightx = weight_signinout;
c.gridx = 2;
JTextField blank2 = new JTextField();
blank2.setEditable(false);
table.add(blank2, c);
c.weightx = weight_time;
c.gridx = 3;
JTextField totaltime = new JTextField("*TOTAL*");
totaltime.setEditable(false);
table.add(totaltime, c);
if (admin) {
c.weightx = weight_delete;
c.gridx = 4;
table.add(applyButton, c);
}
}
public void initNewButtonRow(GridBagConstraints c) {
c.weightx = weight_sessnum;
c.gridx = 0;
table.add(addButton, c);
c.weightx = weight_signinout;
c.gridx = 1;
JTextField blank1 = new JTextField();
blank1.setEditable(false);
table.add(blank1, c);
c.weightx = weight_signinout;
c.gridx = 2;
JTextField blank2 = new JTextField();
blank2.setEditable(false);
table.add(blank2, c);
c.weightx = weight_time;
c.gridx = 3;
JTextField blank3 = new JTextField();
blank3.setEditable(false);
table.add(blank3, c);
if (admin) {
c.weightx = weight_delete;
c.gridx = 4;
JTextField blank4 = new JTextField();
blank4.setEditable(false);
table.add(blank4, c);
}
}
public void initColumnHeader(GridBagConstraints c) {
c.weightx = weight_sessnum;
c.gridx = 0;
JTextField sessnum = new JTextField("Session #");
sessnum.setEditable(false);
table.add(sessnum, c);
c.weightx = weight_signinout;
c.gridx = 1;
JTextField signintime = new JTextField("Sign in Time");
signintime.setEditable(false);
table.add(signintime, c);
c.weightx = weight_signinout;
c.gridx = 2;
JTextField signouttime = new JTextField("Sign out Time");
signouttime.setEditable(false);
table.add(signouttime, c);
c.weightx = weight_time;
c.gridx = 3;
JTextField time = new JTextField("Time");
time.setEditable(false);
table.add(time, c);
if (admin) {
c.weightx = weight_delete;
c.gridx = 4;
JTextField delete = new JTextField("Delete");
delete.setEditable(false);
table.add(delete, c);
}
}
@Override
public void revalidate() {
if (sessionRows != null) {
int i = 1;
for (SessionRow sr : sessionRows) {
sr.sessionnum.setText("Session " + i);
i++;
}
}
super.revalidate();
}
}
public TimeChart(boolean admin) {
super();
this.admin = admin;
volLabel = new JLabel("Billy");
timeTable = new TimeTable();
this.setSize(900, 900);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initFrame();
this.setVisible(true);
scrollDown();
}
public void initFrame() {
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.weighty = 0.0;
c.gridx = 0;
c.gridy = 0;
this.add(title, c);
c.weightx = 1.0;
c.weighty = 0.0;
c.gridx = 0;
c.gridy = 1;
this.add(volLabel, c);
c.weightx = 1.0;
c.weighty = 1.0;
c.gridx = 0;
c.gridy = 2;
this.add(timeTable, c);
}
public void scrollDown() {
JScrollBar bar = timeTable.scrollPane.getVerticalScrollBar();
bar.setValue(bar.getMaximum());
}
public void applyAllChanges() {
}
}
Thanks in advance, I really appreciate it.