In want to add a JScrollpane to my stopwatch program, so if the laptime become more and more the scrollpane should show up and allow the user to scroll.
I tried to add the textArea which I want to have in the scrollpane, but it doesn't show a scrollpane.
public class GUI_VA6 implements ActionListener {
private JPanel pan;
private JFrame frame;
private JScrollPane vertical;
private JButton Laptime;
private JButton Start;
private JButton Stop;
private JLabel label;
private JTextArea textArea;
SimpleStopwatch simple = new SimpleStopwatch();
SimpleStopwatch.StopwatchUpdateListener sss;
double ghz;
String lapTimeString;
int countLap=1;
public GUI_VA6() {
frame = new JFrame();
frame.setTitle("Stopwatch");
label = new JLabel("Current time:");
textArea = new JTextArea();
pan = new JPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Laptime = new JButton("Laptime");
Laptime.setEnabled(false);
Start = new JButton("Start");
Stop = new JButton("Stop");
Stop.setVisible(false);
Start.setVisible(true);
Laptime.addActionListener(this);
Start.addActionListener(this);
Stop.addActionListener(this);
pan.add(Laptime);
pan.add(Stop);
pan.add(Start);
frame.add(pan);
vertical=new JScrollPane(textArea);
vertical.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
frame.add(vertical);
Container c;
c = frame.getContentPane();
c.setLayout(new java.awt.BorderLayout()); // immer so
c.add(pan, BorderLayout.SOUTH);
c.add(textArea, BorderLayout.CENTER);
c.add(label, BorderLayout.NORTH);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.setSize(500, 500);
You are adding your scrollpane to the container (frame.add is equivalent to frame.getContentPane().add), THEN changing the layout manager of the container, which isn't a good idea.
Remove
frame.add(vertical);
And replace
c.add(textArea, BorderLayout.CENTER);
with
c.add(vertical, BorderLayout.CENTER);
Related
I'm currently building GUI with Java Swing.
My current code produces this.
The JTextArea of Product List makes the GUI looks awkward, how can I make the JTextArea looks like this, where it seems to have an extra row:
The GroupLayout code I'm using is:
gr.setVerticalGroup(gr.createSequentialGroup()
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(productName).addComponent(productText).addComponent(productList))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(amount).addComponent(amountText).addComponent(prodScroll))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(description).addComponent(desScroll))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(addButton).addComponent(remButton)));
gr.setHorizontalGroup(gr.createSequentialGroup()
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(productName).addComponent(amount).addComponent(description).addComponent(addButton))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(productText).addComponent(amountText).addComponent(desScroll).addComponent(remButton))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(productList).addComponent(prodScroll)));
I think the minority of people would choose to use GridBagLayout. However, I dislike it (among with GroupLayout) since it is "hard to use". I use nested panels instead with various Layout Managers. Using only BorderLayout and GridLayout you can achieve something like the following example, which is totally resizable, giving emphasis to "interaction" components (I mean, there is no reason to resize a constant-texted JLabel, right?)
I did not add any comments in purpose, so you can experiment with constants (and layout constraints) and see their reason of existence while having the documentations opened.
Code:
public class NestedLayoutManagersExample extends JFrame {
private static final long serialVersionUID = -7042997375941726246L;
private static final int labelsWidth = 80;
private static final int textFieldColumns = 15;
private static final int spaceBetweenAllComponents = 10;
public NestedLayoutManagersExample() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel contentPane = new JPanel(new GridLayout(1, 2, 50, 50));
contentPane.setBorder(BorderFactory.createEmptyBorder(spaceBetweenAllComponents, spaceBetweenAllComponents,
spaceBetweenAllComponents, spaceBetweenAllComponents));
setContentPane(contentPane);
add(createLeftPanel());
add(createRightPanel());
setLocationByPlatform(true);
pack();
}
private Component createRightPanel() {
JPanel mainPanel = new JPanel(new BorderLayout());
JLabel productListLabel = new JLabel("Product list");
mainPanel.add(productListLabel, BorderLayout.PAGE_START);
JList<String> productList = new JList<>();
DefaultListModel<String> listModel = new DefaultListModel<>();
Arrays.asList("Small Chair", "Big Chair", "Flying Chair").forEach(listModel::addElement);
productList.setModel(listModel);
JScrollPane listScrollPane = new JScrollPane(productList);
mainPanel.add(listScrollPane, BorderLayout.CENTER);
return mainPanel;
}
private Component createLeftPanel() {
JPanel mainPanel = new JPanel(new BorderLayout(spaceBetweenAllComponents, spaceBetweenAllComponents));
JPanel topPanel = new JPanel(new GridLayout(2, 1, spaceBetweenAllComponents, spaceBetweenAllComponents));
topPanel.add(createStraightPanel("Product Name"));
topPanel.add(createStraightPanel("Amount"));
mainPanel.add(topPanel, BorderLayout.PAGE_START);
JPanel centerPanel = new JPanel(new BorderLayout());
JLabel label = new JLabel("<html><p style='width:" + labelsWidth + "px';> Description");
label.setVerticalAlignment(JLabel.TOP);
centerPanel.add(label, BorderLayout.LINE_START);
centerPanel.add(createTextAreaPanel());
mainPanel.add(centerPanel, BorderLayout.CENTER);
return mainPanel;
}
private JPanel createTextAreaPanel() {
JPanel mainPanel = new JPanel(new BorderLayout(spaceBetweenAllComponents, spaceBetweenAllComponents));
JTextArea textArea = new JTextArea(1, textFieldColumns);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
mainPanel.add(textAreaScrollPane, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel(new BorderLayout());
JButton addButton = new JButton("Add");
buttonsPanel.add(addButton, BorderLayout.LINE_START);
JButton removeButton = new JButton("Remove");
buttonsPanel.add(removeButton, BorderLayout.LINE_END);
mainPanel.add(buttonsPanel, BorderLayout.PAGE_END);
return mainPanel;
}
private Component createStraightPanel(String labelText) {
JPanel mainPanel = new JPanel(new BorderLayout());
JLabel label = new JLabel("<html><p style='width:" + labelsWidth + "px';>" + labelText);
mainPanel.add(label, BorderLayout.LINE_START);
JTextField textField = new JTextField(textFieldColumns);
mainPanel.add(textField, BorderLayout.CENTER);
return mainPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new NestedLayoutManagersExample().setVisible(true));
}
}
Preview:
This is my first post so please forgive me if I am not following the rules correctly.
I am trying to do something relatively simple in Java. I want to make a JTextArea scrollable. I am aware this has been asked before (Java :Add scroll into text area). However, when I follow this example by adding JTextArea to JScrollPane my JTextArea does not become scrollable. What is it that I am missing?
Here is my code:
import ...;
public class MyControlPanel extends JPanel {
//Declare variables
private JComboBox accountsBox;
private String[] accType = {"Current Account", "Savings Account"};
private JLabel selAccType, initDeposit, logLabel, simLabel;
private JTextField depositText;
private JTextArea log;
private JScrollPane scroll;
private JButton createAccount, start, stop;
private JPanel panel1, panel2, panel3, panel4, panel5, panel6;
private Timer timer;
private MyAccount theAccount;
private Random randNum1, randNum2;
private DecimalFormat df;
//Constructor
public MyControlPanel() {
//Create instances:
selAccType = new JLabel("Please select account type: "); //JLabel
initDeposit = new JLabel("Input initial deposit: ");
logLabel = new JLabel("Log:");
simLabel = new JLabel();
accountsBox = new JComboBox(accType); //JComboBox
depositText = new JTextField("0"); // JTextField
log = new JTextArea(); //JTextArea
scroll = new JScrollPane(log); //JScrollPane
createAccount = new JButton("Create Account"); //JButton
start = new JButton("Start");
stop = new JButton("Stop");
panel1 = new JPanel(); //JPanel
panel2 = new JPanel();
panel3 = new JPanel();
panel4 = new JPanel();
panel5 = new JPanel();
panel6 = new JPanel();
timer = new Timer(); //Timer
df = new DecimalFormat("#.00");
//Add ActionListeners
createAccount.addActionListener(new ActionListener() {...});
start.addActionListener(new ActionListener() {...});
stop.addActionListener(new ActionListener() {...});
//Set JTextField size
depositText.setColumns(5);
//Set JTextArea size
log.setPreferredSize(new Dimension(780, 150));
//Set panel size
panel1.setPreferredSize(new Dimension(500, 500));
panel2.setPreferredSize(new Dimension(800, 50));
panel3.setPreferredSize(new Dimension(500, 50));
panel4.setPreferredSize(new Dimension(500, 50));
panel5.setPreferredSize(new Dimension(800, 25));
panel6.setPreferredSize(new Dimension(800, 200));
//Set layout in panel5 to align left
panel6.setLayout(new FlowLayout(FlowLayout.LEFT));
//Add components to each panel
addPanels();
//Place objects in the framed window
this.add(panel1);
this.add(panel2);
this.add(panel3);
this.add(panel4);
this.add(panel5);
this.add(panel6);
}
public void addPanels() {...}
public void removePanels() {...}
}
You need to change:
log.setPreferredSize(new Dimension(780, 150));
to:
scroll.setPreferredSize(new Dimension(780, 150));
I have several GUI elements added to a JPanel. The JPanel is added to a JScrollPane. The JScrollPane is added to a JFrame (CENTER section of a BorderLayout).
At times I need to remove the JScrollPane and make the space available for other elements. I've provided a method for that. Want to make sure that this method disposes of all resources used by the old JScrollPane and makes them available for Garbage Collection. Please see code below. Is my clearCenter() method sufficient for this task? Is there a better way to do it?
Thanks.
import java.awt.*;
import javax.swing.*;
public class MyGui extends JFrame {
private JScrollPane scroll;
private JPanel panel;
private JButton button1;
private JButton button2;
private JButton button3;
private JButton button4;
// Constructor
public MyGui() {
super("Playback");
setSize(250, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BorderLayout layout = new BorderLayout();
setLayout(layout);
panel = new JPanel();
GridLayout grid = new GridLayout(0, 1, 30, 30);
panel.setLayout(grid);
button1 = new JButton("Button1");
button2 = new JButton("Button2");
button3 = new JButton("Button3");
button4 = new JButton("Button4");
panel.add(button1);
panel.add(button2);
panel.add(button3);
panel.add(button4);
scroll = new JScrollPane(panel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(scroll, BorderLayout.CENTER);
add(new JLabel("South", JLabel.CENTER),BorderLayout.SOUTH);
add(new JLabel("North", JLabel.CENTER),BorderLayout.NORTH);
add(new JLabel("East", JLabel.CENTER),BorderLayout.EAST);
add(new JLabel("West", JLabel.CENTER),BorderLayout.WEST);
setVisible(true);
}
public void clearCenter() {
button1 = null;
button2 = null;
button3 = null;
button4 = null;
panel = null;
remove(scroll);
scroll = null;
}
}
At times I need to remove the JScrollPane and make the space available for other elements.
Use a CardLayout as shown in this answer. And I would not worry too much about disposing of a scroll pane, keep it in memory. When it is next needed, update the scroll pane contents then flip back to that card in the layout.
Resetting the content of the scroll-pane can be done like below. Activate the first button to see the button panel replaced by the yellow panel as the view of the scroll-pane. Note that this code is a 'ready to run' MCVE (with a main(String[]) to show it onscreen). Please post MCVE code in future.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class MyGui extends JFrame {
private JScrollPane scroll;
private JPanel panel;
private JPanel brightPanel;
private JButton button1;
private JButton button2;
private JButton button3;
private JButton button4;
// Constructor
public MyGui() {
super("Playback");
setSize(250, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BorderLayout layout = new BorderLayout();
setLayout(layout);
// create the panel, but don't add it yet.
brightPanel = new JPanel();
brightPanel.setBackground(Color.YELLOW);
panel = new JPanel();
GridLayout grid = new GridLayout(0, 1, 30, 30);
panel.setLayout(grid);
button1 = new JButton("Button1");
button2 = new JButton("Button2");
button3 = new JButton("Button3");
button4 = new JButton("Button4");
panel.add(button1);
panel.add(button2);
panel.add(button3);
panel.add(button4);
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
changeViews();
}
};
button1.addActionListener(listener);
scroll = new JScrollPane(panel,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(scroll, BorderLayout.CENTER);
add(new JLabel("South", JLabel.CENTER), BorderLayout.SOUTH);
add(new JLabel("North", JLabel.CENTER), BorderLayout.NORTH);
add(new JLabel("East", JLabel.CENTER), BorderLayout.EAST);
add(new JLabel("West", JLabel.CENTER), BorderLayout.WEST);
setVisible(true);
}
public void changeViews() {
scroll.setViewportView(brightPanel);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new MyGui();
}
};
SwingUtilities.invokeLater(r);
}
}
I am trying to resize the JPanels but there is a space under it . Here is a link to show :
And this is the code :
import java.awt.*;
import javax.swing.*;
public class Ex1 extends JFrame{
private JTextArea textarea = new JTextArea ();
private JTextField field = new JTextField ();``
private JButton buton = new JButton ("Trimite");
public Ex1(){
JPanel panel = new JPanel (new BorderLayout(2,2));
JPanel panel1 = new JPanel (new BorderLayout(2,2));
JPanel panel2 = new JPanel (new BorderLayout(2,2));
JLabel label1 = new JLabel ("Mesaje");
JLabel label2 = new JLabel ("Scrieti un mesaj");
panel1.setPreferredSize(new Dimension(350,100));
panel2.setPreferredSize(new Dimension(350,25));
panel1.add(label1, BorderLayout.NORTH);
panel1.add(textarea, BorderLayout.CENTER);
panel2.add(label2, BorderLayout.WEST);
panel2.add(field, BorderLayout.CENTER);
panel2.add(buton, BorderLayout.EAST);
setLayout(new GridLayout(2,1,1,1));
panel.add(panel1, BorderLayout.NORTH);
panel.add(panel2, BorderLayout.CENTER);
add(panel);
}
public static void main(String[] args) {
JFrame frame = new Ex1();
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
You are setting a layout for a frame to GridLayout in which all components are given equal size. You have two rows, add(panel) adds the panel to the first row of the grid. The second row is left empty. See How to Use GridLayout.
Comment out setLayout(new GridLayout(2,1,1,1)); and the extra space should go away. When you comment this line the layout of frame's content pane will be BorderLayout. The default layout of the JFrame is BorderLayout. So add(panel); will add the panel to the center of the frame's content pane. As a result the panel should occupy all the available space.
As a side note, avoid setPreferredSize(), usually it is not necessary, see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing for details.
You can specify the number of rows and columns for a text area and wrap it in the scroll pane, ie:
textArea = new JTextArea(5, 20);
JScrollPane scrollPane = new JScrollPane(textArea);
For more details see How to Use Text Areas
EDIT: example of getPreferredSize()
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;
public class Ex1 extends JPanel{
private JTextArea textarea = new JTextArea ();
private JTextField field = new JTextField ();
private JButton buton = new JButton ("Trimite");
public Ex1() {
setLayout(new BorderLayout());
JPanel panel1 = new JPanel (new BorderLayout(2,2));
JPanel panel2 = new JPanel (new BorderLayout(2,2));
JLabel label1 = new JLabel ("Mesaje");
JLabel label2 = new JLabel ("Scrieti un mesaj");
panel1.add(label1, BorderLayout.NORTH);
panel1.add(new JScrollPane(textarea), BorderLayout.CENTER);
panel2.add(label2, BorderLayout.WEST);
panel2.add(field, BorderLayout.CENTER);
panel2.add(buton, BorderLayout.EAST);
add(panel1, BorderLayout.CENTER);
add(panel2, BorderLayout.SOUTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(350, 300);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
Ex1 panel = new Ex1();
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
});
}
}
You need to resize the JFrame not the JPanel. Try:
this.setPreferredSize(new Dimension(350, 25);// in Ex1
Or in your main method:
frame.setPreferredSize(new Dimension(350, 25);
I am trying to fit my image below into the JButton but the image is not fully fit into the jbutton and there is a gap between the image and the button borders.How do i make the image appear fully on my JButton jbtstart?In addition how do i shift the JPanel containing the JButtons to another location as it appears at the top?
private JButton jbtstart;
private JButton jbtabout = new JButton("About");
private JButton jbtcredits = new JButton("Credits");
private JButton jbtexit = new JButton("Exit");
private JButton jbtImg;
//private static int gridSize = 2;
public GUI_interface()
{
super("GUIinterface");
}
public void createAndDisplayGUI()
{
jbtstart= new JButton(new ImageIcon("C:\\Users\\Desktop\\start button.png"));
jbtstart.setLayout(new BorderLayout());
JLabel back=new JLabel(new ImageIcon("C:\\Users\\Desktop\\background.png"));
JPanel p = new JPanel();
//p.setLayout(null);
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(2,2,80,15));
back.setLayout(new FlowLayout());
p1.add(jbtstart);
p1.add(jbtabout);
p1.add(jbtcredits);
p1.add(jbtexit);
back.add(p1);
jbtstart.addActionListener(this);
jbtabout.addActionListener(this);
jbtcredits.addActionListener(this);
jbtexit.addActionListener(this);
setContentPane(back);
JFrame frame = new JFrame("f");
frame.setTitle("Cooking App");
frame.setSize(300,250);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(back);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}