how to keep JLabel over JProgressbar - java

This is a part of my java code, in this code I want that the progress bar should always remains under the label (at the back of label), progress bar is under the label when I start the program, but progress bar comes over/upon the label when I click the button and start progress. So please tell how can I keep the label always over the progress bar???
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
public class Test {
JFrame frame = new JFrame();
JLabel label = new JLabel();
JProgressBar bar = new JProgressBar(JProgressBar.VERTICAL,0,100);
JButton button = new JButton();
public static void main(String arg[]) {
new Test();
}
public Test() {
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setLayout(null);
label.setOpaque(true);
label.setBackground(Color.BLACK);
label.setBounds(100,100,100,50);
bar.setBounds(140,25,20,200);
button.setBounds(220,100,50,50);
button.addActionListener(new Progress());
frame.add(label);
frame.add(bar);
frame.add(button);
frame.setVisible(true);
}
class Progress extends SwingWorker<Void, Void> implements ActionListener {
public Void doInBackground() {
for(int i=0; i<101; i++) {
bar.setValue(i);
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
public void actionPerformed(ActionEvent e) {
this.execute();
}
}
}

I'm not sure why you're trying to do what you are, when JProgressBar already provides the means to display a String value...
See JProgressBar#setStringPainted for more details...
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ProgressBarTest {
public static void main(String[] args) {
new ProgressBarTest();
}
public ProgressBarTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
JProgressBar pb = new JProgressBar();
pb.setValue(0);
pb.setStringPainted(true);
pb.setString("Look ma, no hands");
frame.add(pb);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
SwingWorker worker = new SwingWorker() {
#Override
protected Object doInBackground() throws Exception {
for (int index = 0; index < 1000; index++) {
int progress = (int)Math.round((index / 1000f) * 100);
setProgress(progress);
Thread.sleep(10);
}
return null;
}
};
worker.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
int value = (int) evt.getNewValue();
System.out.println(value);
pb.setValue(value);
}
}
});
worker.execute();
}
});
}
}
Updated
Now, if you "really" want to put a label on top of a progress bar, there are some tricks you can do, for example...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ProgressBarTest {
public static void main(String[] args) {
new ProgressBarTest();
}
public ProgressBarTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JLabel label = new JLabel("I feel the need for speed");
JProgressBar pb = new JProgressBar();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.ipady = 20;
frame.add(pb, gbc);
gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.insets = new Insets(5, 0, 5, 0);
frame.add(label, gbc);
frame.add(pb, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
SwingWorker worker = new SwingWorker() {
#Override
protected Object doInBackground() throws Exception {
for (int index = 0; index < 1000; index++) {
int progress = (int) Math.round((index / 1000f) * 100);
setProgress(progress);
Thread.sleep(10);
}
return null;
}
};
worker.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
int value = (int) evt.getNewValue();
System.out.println(value);
pb.setValue(value);
}
}
});
worker.execute();
}
});
}
}
Basically, this places both the label and progress bar at the same location within the GridBagLayout...

Based on this post and idea that #MadProgrammer gave me
"You can use:
Initialising:
progressBar.setStringPainted(true);
Updating:
progressBar.setValue(newValue);
progressBar.setString(newValue + "%");"
Source of this answer :
How to add text on jprogressbar?
My answer to this problem is
Code:
JFrame frame = new JFrame();
JProgressBar bar = new JProgressBar(JProgressBar.HORIZONTAL, 0, 100);
JButton button = new JButton("Button");
public static void main(String arg[]) {
new Test();
}
public Test() {
bar.setStringPainted(true);
bar.setString("I am a JProgressBar and ready to go here");
button.addActionListener(new Progress());
JPanel pane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 40; //make this component tall
c.weightx = 0.0;
c.gridwidth = 2;
c.gridx = 2;
c.gridy = 2;
pane.add(bar, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.5;
c.gridx = 2;
c.gridy = 3;
pane.add(button, c);
frame.add(pane);
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
class Progress extends SwingWorker<Void, Void> implements ActionListener {
#Override
public Void doInBackground() {
for (int i = 0; i < 101; i++) {
bar.setValue(i);
bar.setString(Integer.toString(i) + "%");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
public void actionPerformed(ActionEvent e) {
this.execute();
}
}
}
Output:

Related

In Java, how could I make a letter flash on the screen depending on a BPM value the user provides?

With Swing, I've created a window and want a letter to flash on the screen depending on the BPM (Beats per minute) the user inputs, and I was wondering how I would go about timing the flashing accurately. I tried using a Swing Timer but it is not very accurate and I see a lot of pauses or lag. I've heard something about using System.nanoTime() and System.currentTimeMillis() but have no clue how to implement them to create a timer. Any help would be appreciated!
Note.java
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.*;
import java.awt.*;
public class Note extends JFrame implements ActionListener {
JPanel mainScreen = new JPanel();
JPanel south = new JPanel();
JPanel north = new JPanel();
//emptyNumberMain = how many empty panels you want to use
public int emptyNumberMain = 2;
JPanel[] emptyMain = new JPanel[emptyNumberMain];
JLabel title = new JLabel("Fretboard Trainer!");
JButton start = new JButton("Start!");
public static void main(String[] args) {
new Note();
}
public Note() {
super("Random Note!");
setSize(300,300);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//creates emptyNumberMain amount of empty panels
for (int i = 0; i < emptyNumberMain; i++) {
emptyMain[i] = new JPanel();
}
mainScreen.setLayout(new BorderLayout());
south.setLayout(new GridLayout(1,1));
south.add(emptyMain[0]);
south.add(start);
south.add(emptyMain[1]);
north.setLayout(new GridLayout(1,2));
north.add(title);
title.setHorizontalAlignment(JLabel.CENTER);
title.setFont(title.getFont().deriveFont(32f));
start.addActionListener(this);
mainScreen.add(north, BorderLayout.NORTH);
mainScreen.add(south, BorderLayout.SOUTH);
add(mainScreen);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == start) {
dispose();
new RandomNote();
}
}
}
RandomNote.java
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.util.Random;
import javax.swing.Timer;
import javax.swing.JSlider;
import java.awt.event.*;
import java.awt.*;
public class RandomNote extends JFrame {
JPanel noteScreen = new JPanel();
JPanel center = new JPanel();
JPanel southSlider = new JPanel();
JLabel bpm = new JLabel();
//emptyNumber = how many empty panels you want to use
int emptyNumber = 2;
JPanel[] empty = new JPanel[emptyNumber];
JLabel rndNote = new JLabel();
JSlider slider = new JSlider(0,200,100);
Timer timer2 = new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
bpm.setText(Integer.toString(slider.getValue()));
timer.setDelay((int) ((60.0/slider.getValue()) * 1000));
}
});
public RandomNote() {
super("Random Notes!");
timer.start();
timer2.start();
setSize(500,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
//creates variable emptyNumber amount of empty panels
for (int i = 0; i < emptyNumber; i++) {
empty[i] = new JPanel();
}
noteScreen.setLayout(new BorderLayout());
center.setLayout(new GridLayout(1,1));
center.add(rndNote);
southSlider.setLayout(new GridLayout(3,1));
slider.setLabelTable(slider.createStandardLabels(20));
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setMinorTickSpacing(5);
slider.setMajorTickSpacing(20);
southSlider.add(slider);
southSlider.add(bpm);
rndNote.setHorizontalAlignment(JLabel.CENTER);
rndNote.setFont(rndNote.getFont().deriveFont(32f));
noteScreen.add(center, BorderLayout.CENTER);
noteScreen.add(southSlider, BorderLayout.SOUTH);
add(noteScreen);
setVisible(true);
}
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
rndNote.setText(noteOutput());
}
});
public static String noteOutput() {
Random rand = new Random();
String[] note = {"A", "B", "C", "D", "E", "F", "G"};
int randNum = rand.nextInt(7);
return note[randNum];
}
}
The immediate thing that jumps out at me is this...
Timer timer2 = new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
bpm.setText(Integer.toString(slider.getValue()));
timer.setDelay((int) ((60.0/slider.getValue()) * 1000));
}
});
Why do you need to update the text and reset the timer every 100 milliseconds?
So, the simple answer would be to use a ChangeListener on the JSlider to determine when the slider's value changes. I'd recommend having a look at How to Use Sliders for more details
As a runnable concept...
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private AnimatableLabel label;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
label = new AnimatableLabel("BMP");
label.setHorizontalAlignment(JLabel.CENTER);
add(label, gbc);
label.start();
JSlider slider = new JSlider(10, 200);
slider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
label.setBPM(slider.getValue());
}
});
slider.setValue(60);
add(slider, gbc);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class AnimatableLabel extends JLabel {
private Timer pulseTimer;
private Timer fadeTimer;
private double bpm = 60;
private double alpha = 0;
private Long pulsedAt;
public AnimatableLabel(String text, Icon icon, int horizontalAlignment) {
super(text, icon, horizontalAlignment);
setBackground(Color.RED);
initTimer();
}
public AnimatableLabel(String text, int horizontalAlignment) {
super(text, horizontalAlignment);
setBackground(Color.RED);
initTimer();
}
public AnimatableLabel(String text) {
super(text);
setBackground(Color.RED);
initTimer();
}
public AnimatableLabel(Icon image, int horizontalAlignment) {
super(image, horizontalAlignment);
setBackground(Color.RED);
initTimer();
}
public AnimatableLabel(Icon image) {
super(image);
setBackground(Color.RED);
initTimer();
}
public AnimatableLabel() {
setBackground(Color.RED);
initTimer();
}
public void start() {
updateTimer();
}
public void stop() {
pulseTimer.stop();
fadeTimer.stop();
}
protected void initTimer() {
pulseTimer = new Timer((int)(getDuration()), new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pulsedAt = System.currentTimeMillis();
alpha = 1.0;
repaint();
}
});
pulseTimer.setInitialDelay(0);
pulseTimer.setCoalesce(true);
fadeTimer = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (pulsedAt == null) {
return;
}
long fadingDuration = System.currentTimeMillis() - pulsedAt;
alpha = 1.0 - (fadingDuration / getDuration());
if (alpha > 1.0) {
alpha = 1.0;
} else if (alpha < 0.0) {
alpha = 0.0;
}
repaint();
}
});
fadeTimer.setCoalesce(true);
}
protected double getDuration() {
return (60.0 / bpm) * 1000.0;
}
protected void updateTimer() {
fadeTimer.stop();
pulseTimer.stop();
pulseTimer.setDelay((int)getDuration());
pulseTimer.start();
fadeTimer.start();
}
public void setBPM(double bpm) {
this.bpm = bpm;
setText(Double.toString(bpm));
updateTimer();
}
public double getBPM() {
return bpm;
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive((float)alpha));
g2d.setColor(Color.RED);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
super.paintComponent(g);
}
}
}

JScrollPane shrink/collapse on window minimize

I have a JScrollPane which contains a JTextArea. When the window is minimized and then restored, the JScrollPane will then collapse on itself. Note that this squish only happens if the text in the JTextArea exceeds the given width and/or height of the JTextArea (i.e., the horizontal or vertical scrollbars appear).
This question here: JScrollpane loses size after minimize poses the same problem, but the issue is never addressed, other than to add weightx, weighty, and fill constraints to the JScrollPane, which I already had to begin with.
Below is a simplified example that demonstrates the problem. How can I get the JScrollPane to sustain its size after the window is minimized and restored?
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EtchedBorder;
public class GUITest implements ActionListener {
JButton button = new JButton("Button");
JTextArea textArea = new JTextArea();
SwingWorker<String, String> mySwingWorker = null;
public static void main(String[] args) throws IOException {
GUITest tracer = new GUITest();
}
public GUITest() throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createAndShowGUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public void createAndShowGUI() throws IOException {
JFrame frame = new JFrame("GUI Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints mainPanelConstraints = new GridBagConstraints();
mainPanelConstraints.gridx = 0;
mainPanelConstraints.gridy = 0;
mainPanelConstraints.fill = GridBagConstraints.BOTH;
button.addActionListener(this);
mainPanel.add(button, mainPanelConstraints);
mainPanelConstraints.gridx = 0;
mainPanelConstraints.gridy = 1;
mainPanelConstraints.fill = GridBagConstraints.BOTH;
mainPanel.add(buildTextAreaPanel(), mainPanelConstraints);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setVisible(true);
}
private JPanel buildTextAreaPanel() {
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new GridBagLayout());
GridBagConstraints textAreaPanelConstraints = new GridBagConstraints();
textAreaPanel.setBorder(BorderFactory.createTitledBorder(new EtchedBorder(EtchedBorder.RAISED), "TextArea"));
textArea.setColumns(30);
textArea.setRows(15);
textArea.setEditable(false);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
textAreaScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
textAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
textAreaPanelConstraints.gridx = 0;
textAreaPanelConstraints.gridy = 0;
textAreaPanelConstraints.weightx = 1.0;
textAreaPanelConstraints.weighty = 1.0;
textAreaPanelConstraints.fill = GridBagConstraints.BOTH;
textAreaPanel.add(textAreaScrollPane, textAreaPanelConstraints);
return textAreaPanel;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
mySwingWorker = new MySwingWorker();
mySwingWorker.execute();
}
}
private class MySwingWorker extends SwingWorker<String, String> {
public String doInBackground() throws Exception {
for (int i = 0; i < textArea.getRows(); i++) {
publish("text\n");
}
publish("more text\n");
return "Done.";
}
public void process(List<String> chunks) {
for (String msg : chunks) {
textArea.append(msg);
}
}
public void done() {
try {
String msg = get();
textArea.append("\n" + msg);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
You need to set the weightx and weighty in both layouts. In createAndShowGui, set mainPanelConstraints.weightx and mainPanelConstraints.weighty to 1 before adding the text area panel.
Set the layout of the parent Container (the content pane) to FlowLayout
...
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(mainPanel);
...
I solved the shrinkage problem in this particular code example by removing all GridBagLayouts and replacing them with BorderLayouts. I have no idea why a JScrollPane reacts the way you discovered when using a GridBagLayout.
I felt real uncomfortable starting the Event Dispatch thread from the class constructor. I moved the SwingUtilities invokeLater into the main method.
Anyway, here's the code.
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EtchedBorder;
public class JScrollPaneTest implements ActionListener {
JButton button = new JButton("Button");
JTextArea textArea = new JTextArea();
SwingWorker<String, String> mySwingWorker = null;
public static void main(String[] args) throws IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new JScrollPaneTest().createAndShowGUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public JScrollPaneTest() throws IOException {
}
public void createAndShowGUI() throws IOException {
JFrame frame = new JFrame("JScrollPane Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(true);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(button, BorderLayout.NORTH);
mainPanel.add(buildTextAreaPanel(), BorderLayout.CENTER);
button.addActionListener(this);
frame.add(mainPanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private JPanel buildTextAreaPanel() {
JPanel textAreaPanel = new JPanel();
textAreaPanel.setLayout(new BorderLayout());
textAreaPanel.setBorder(BorderFactory.createTitledBorder(
new EtchedBorder(EtchedBorder.RAISED), "TextArea"));
textArea.setColumns(30);
textArea.setRows(15);
textArea.setEditable(false);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
textAreaPanel.add(textAreaScrollPane, BorderLayout.CENTER);
return textAreaPanel;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
mySwingWorker = new MySwingWorker();
mySwingWorker.execute();
}
}
private class MySwingWorker extends SwingWorker<String, String> {
public String doInBackground() throws Exception {
for (int i = 0; i < textArea.getRows(); i++) {
publish("text\n");
}
publish("more text\n");
return "Done.";
}
public void process(List<String> chunks) {
for (String msg : chunks) {
textArea.append(msg);
}
}
public void done() {
try {
String msg = get();
textArea.append("\n" + msg);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}

Add and remove button dynamically in Swing frame

I'm developing a swing application. In that I've a JFrame which add JTextfield and JButton dynamically on the button click.and remove the created components if the user clicks the same button.
In the below screen image , when user clicks ADD button new row was added, and text was changed to REMOVE like in 2nd image.
New Row added and previous button text changed to REMOVE.
Now, if I click the REMOVE button, then the newly added row has to dispose and then button has to change the text again to ADD.
I've tried till adding the components, but I stuck up with removing the newly added row.
Anyone please guide me to achieve this.
Below is my code.
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ButtonAddDynamic implements ActionListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ButtonAddDynamic().createAndShowGUI();
}
});
}
private JFrame frame;
private JPanel panel = new JPanel(new GridBagLayout());
private GridBagConstraints constraints = new GridBagConstraints();
private List fields = new ArrayList();
private List fieldButton = new ArrayList();
private List fieldFile = new ArrayList();
private static int countReport = 0;
String files = null;
int y = 2;
protected void createAndShowGUI() {
try {
UIManager
.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
}
String[] labels = { "VALIDATION FORM" };
for (String label : labels)
addColumn(label);
frame = new JFrame("Add Button Dynamically");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(panel));
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// Set the default button to button1, so that when return is hit, it
// will hit the button1
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
private void addColumn(String labelText) {
constraints.gridx = fields.size();
constraints.gridy = 1;
panel.add(new JLabel(labelText), constraints);
constraints.gridy = 2;
final JTextField field = new JTextField(40);
field.setEditable(false);
panel.add(field, constraints);
fields.add(field);
// constraints.gridy=3;
constraints.gridx = fields.size() + fieldButton.size();
final JButton button = new JButton("ADD");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (button.getText().equals("ADD")) {
button.setText("REMOVE");
addRowBelow();
frame.pack();
} else if (button.getText().equals("REMOVE")) {
button.setText("ADD");
frame.pack();
}
}
});
panel.add(button, constraints);
fieldButton.add(button);
panel.revalidate(); // redo layout for extra column
}
private void addRowBelow() {
y++;
constraints.gridy = y;
// System.out.println(fields.size());
for (int x = 0; x < fields.size(); x++) {
constraints.gridx = x;
final JTextField field = new JTextField(40);
field.setEditable(false);
panel.add(field, constraints);
constraints.gridx = x + 1;
final JButton button = new JButton("ADD");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (button.getText().equals("ADD")) {
button.setText("REMOVE");
addRowBelow();
frame.pack();
} else if (button.getText().equals("REMOVE")) {
button.setText("ADD");
frame.pack();
}
}
});
panel.add(button, constraints);
}
}
public void actionPerformed(ActionEvent ae) {
if ("Add Another TextField and Button".equals(ae.getActionCommand())) {
addRowBelow();
frame.pack();
frame.setLocationRelativeTo(null);
}
}
}
Trying to use GridBagLayout is making this very complicated for you. A nested layout scheme is much easier to work with when you are doing this type of thing.
See this MCVE:
I'm not sure I understood your intended functionality 100% correct but I don't think it's as important as the layouts.
My layout scheme is as follows:
This is nice because BoxLayout will handle the vertical listing without much hullabaloo. Instead of having to wrangle with GridBagConstraints, the text field and button are contained together by a panel.
import javax.swing.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Insets;
public class FieldList implements Runnable, ActionListener {
public static void main(String... args) {
SwingUtilities.invokeLater(new FieldList());
}
final int maxFields = 2;
JFrame frame;
JPanel listing;
#Override
public void run() {
frame = new JFrame("Text Field Listing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel content = new JPanel(new BorderLayout());
content.add(new JLabel("Input Form", JLabel.CENTER), BorderLayout.NORTH);
listing = new JPanel();
listing.setLayout(new BoxLayout(listing, BoxLayout.Y_AXIS));
content.add(listing, BorderLayout.CENTER);
frame.setContentPane(content);
addNewField();
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
void addNewField() {
FieldButtonPair field = new FieldButtonPair();
field.button.addActionListener(this);
listing.add(field);
frame.pack();
}
void removeLastField() {
listing.remove(listing.getComponentCount() - 1);
frame.pack();
}
#Override
public void actionPerformed(ActionEvent ae) {
AddRemoveButton source = (AddRemoveButton)ae.getSource();
if(source.state == AddRemoveButton.State.ADD) {
if(listing.getComponentCount() < maxFields) {
addNewField();
source.setState(AddRemoveButton.State.REMOVE);
}
} else if(source.state == AddRemoveButton.State.REMOVE) {
removeLastField();
source.setState(AddRemoveButton.State.ADD);
}
}
}
class FieldButtonPair extends JPanel {
JTextField field;
AddRemoveButton button;
FieldButtonPair() {
super(new BorderLayout());
field = new JTextField();
add(field, BorderLayout.CENTER);
button = new AddRemoveButton();
add(button, BorderLayout.EAST);
}
#Override
public Dimension getPreferredSize() {
Dimension pref = super.getPreferredSize();
pref.width = Math.max(480, pref.width);
return pref;
}
}
class AddRemoveButton extends JButton {
enum State { ADD, REMOVE }
State state = State.ADD;
AddRemoveButton() {
setText(state.name());
}
void setState(State state) {
setText(state.name());
this.state = state;
}
#Override
public Dimension getPreferredSize() {
Dimension pref = super.getPreferredSize();
Font f = getFont();
FontMetrics fm = getFontMetrics(f);
int w = fm.stringWidth(State.REMOVE.name());
Insets ins = getInsets();
pref.width = (ins.left + w + ins.right);
return pref;
}
}

How to change size of JTextArea

I have three radio buttons that I want to use to change the size of a JTextArea when I click the buttons.
if(rd_7inch.isSelected())
{
jScrollPane2.setSize(200,200);
txt_sysnp.setSize(5,20);
}if(rd_9inch.isSelected())
{
jScrollPane2.setSize(200,200);
txt_sysnp.setSize(5,25);
}if(rd_10inch.isSelected())
{
jScrollPane2.setSize(200,200);
txt_sysnp.setSize(5,30);
}
The important point is that whenever you update the UI you have to call revalidate() on that panel or container so that your changes get apply.
You can also do this by setSize() method.
public void showDialog(){
btnUp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dimSPane.setSize(new Dimension(400,50));
pane.revalidate();
}
});
btnUp.setSize(new Dimension(100,24));
btnDn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dimSPane.setSize(new Dimension(200,25));
pane.revalidate();
}
});
btnDn.setSize(new Dimension(100,24));
dimSPane.setSize(new Dimension(200,25));
Dimension dimtfield = new Dimension();
dimtfield.setSize(new Dimension(200,25));
spane.setMinimumSize(dimSPane);
spane.setMaximumSize(dimSPane);
spane.setPreferredSize(dimSPane);
tfield.setMinimumSize(dimtfield);
tfield.setMaximumSize(dimtfield);
tfield.setPreferredSize(dimtfield);
pane.add(spane);
pane.add(tfield);
pane.add(btnUp);
pane.add(btnDn);
JDialog dlg =new JDialog();dlg.add(pane);
dlg.pack();
dlg.show();
}
It is likely that you components are under the control of a layout manager.
The only means by which you can suggest changes to the size would be to use setColumns and setRows and use a layout manager that respects the preferred size of its components
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TextAreaSize {
public static void main(String[] args) {
new TextAreaSize();
}
public TextAreaSize() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea ta;
public TestPane() {
setLayout(new GridBagLayout());
JRadioButton btnSmall = new JRadioButton(new SizeAction("Small", 2, 10));
JRadioButton btnMed = new JRadioButton(new SizeAction("Medium", 4, 15));
JRadioButton btnLarge = new JRadioButton(new SizeAction("Large", 12, 24));
ButtonGroup bg = new ButtonGroup();
bg.add(btnSmall);
bg.add(btnMed);
bg.add(btnLarge);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.NORTHWEST;
add(btnSmall, gbc);
gbc.gridy++;
add(btnMed, gbc);
gbc.gridy++;
add(btnLarge, gbc);
gbc.gridx++;
gbc.gridy = 0;
gbc.gridheight = GridBagConstraints.REMAINDER;
gbc.anchor = GridBagConstraints.CENTER;
ta = new JTextArea();
add(new JScrollPane(ta), gbc);
btnSmall.doClick();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public class SizeAction extends AbstractAction {
private int rows;
private int columns;
public SizeAction(String name, int rows, int columns) {
putValue(NAME, name);
this.rows = rows;
this.columns = columns;
}
#Override
public void actionPerformed(ActionEvent e) {
ta.setRows(rows);
ta.setColumns(columns);
revalidate();
}
}
}
}

Progress Bar Java

I am using JProgressBar to show progress. But, How to show the progressBar as loading from 0 to 100? I got the code from internet and its working except the progressBar is not loading.
code
progressFrame = new JFrame(); // frame to display progress bar
progressBar = new JProgressBar(0,100);
progressBar.setValue(0);
progressBar.setStringPainted(true);
progressFrame.add(progressBar);
new SwingWorker<Void,Void>()
{
protected Void doInBackground() throws SQLException, ClassNotFoundException
{
Class.forName("oracle.jdbc.driver.OracleDriver");
progressBar.setValue(0);
frame.setEnabled(false); // frame = main frame
//tableclass creates a JTable with data from database
tableclass = new TheDatabaseTable(deptName);//it takes time to create
progressBar.setValue(50);
frame.getContentPane().removeAll();
frame.setContentPane(tableclass);
frame.validate();
frame.repaint();
progressBar.setValue(100);
//progressFrame.dispose();
return null;
};
protected void done()
{
//progressFrame.setVisible(false);
frame.setVisible(true);
progressFrame.dispose();
frame.setEnabled(true);
}
}.execute();
I would appreciate if anyone edit the above code to work. Thank you.
Gotta love code from the internet...oh...
The code you have violates the singe thread rules of Swing and thus, is a bad example.
You have a number of options with SwingWorker. You could publish the progress and use the process method to update the progress bar or you could use a PropertyChangeListener and monitor progress change events created by calling the setProgress method of the SwingWorker
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class SwingWorkerProgress {
public static void main(String[] args) {
new SwingWorkerProgress();
}
public SwingWorkerProgress() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JProgressBar pbProgress;
private JButton start;
public TestPane() {
setBorder(new EmptyBorder(10, 10, 10, 10));
pbProgress = new JProgressBar();
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.gridx = 0;
gbc.gridy = 0;
add(pbProgress, gbc);
start = new JButton("Start");
gbc.gridy++;
add(start, gbc);
start.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
start.setEnabled(false);
ProgressWorker pw = new ProgressWorker();
pw.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
String name = evt.getPropertyName();
if (name.equals("progress")) {
int progress = (int) evt.getNewValue();
pbProgress.setValue(progress);
repaint();
} else if (name.equals("state")) {
SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
switch (state) {
case DONE:
start.setEnabled(true);
break;
}
}
}
});
pw.execute();
}
});
}
}
public class ProgressWorker extends SwingWorker<Object, Object> {
#Override
protected Object doInBackground() throws Exception {
int i = 0;
int max = 2000;
while (i < max) {
i += 10;
int progress = Math.round(((float)i / (float)max) * 100f);
setProgress(progress);
try {
Thread.sleep(25);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
}
You have to use threads for that. Design a class that implements Runnable interface which will update the values like this.
class ProgressBarUpdator implements java.lang.Runnable {
/**
* Progress bar that shows the current status
*/
private javax.swing.JProgressBar jpb = null;
/**
* Progress bar value
*/
private java.lang.Integer value = null;
/**
* Constructor
* #param jpb The progress bar this has to update
*/
public ProgressBarUpdator(javax.swing.JProgressBar jpb) {
this.jpb = jpb;
jpb.setMaximum(100);
}
/**
* Sets the value to the progress bar
* #param value Value to set
*/
public void setValue(java.lang.Integer value) {
this.value = value;
}
/**
* Action of the thread will be executed here. The value of the progress bar will be set here.
*/
public void run() {
do {
if (value != null) {
jpb.setValue((int)java.lang.Math.round(java.lang.Math.floor(value.intValue() * 100 / maximum)));
}
try {
java.lang.Thread.sleep(100L);
} catch (java.lang.InterruptedException ex) {
ex.printStackTrace();
}
} while (value == null || value.intValue() < jpb.getMaximum());
}
}
and in your frame class use progressBar with the new class like this
ProgressBarUpdator ju = new ProgressBarUpdator(progressBar);
new java.lang.Thread(ju).start();
Whenever you want to change the value just use the statement
ju.setValue([Value to set]);
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
public class ProgressBar {
/**
* JProgressBar
*
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("New Window");
frame.setSize(600, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setLayout(new GridBagLayout());
frame.setVisible(true);
//JLabel textLoad = new JLabel();
//textLoad.setText("Loading ....");
JProgressBar progressBar = new JProgressBar();
progressBar.setMinimum(0);
progressBar.setMaximum(100);
progressBar.setStringPainted(true);
progressBar.setIndeterminate(true);
frame.add(progressBar);
for (int i = progressBar.getMinimum(); i <= progressBar.getMaximum(); i++) {
Thread.sleep(500);
progressBar.setValue(i);
}
textLoad.setText("Done !");
}
}
/*
By
Dr. Amit Kumar Kapoor
Assistant Professor, Maharaja Agrasen Institute of Management & Technology, Jagadhri
E-mail ID: akbrightfuture#gmail.com
*/
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class progressbardemo extends JFrame implements ActionListener
{
JProgressBar pb;
JButton b1;
progressbardemo()
{
super("Progressbar");
setLayout(null);
b1=new JButton("Click");
b1.setBackground(Color.yellow);
pb=new JProgressBar(1,100);
pb.setValue(0);
pb.setStringPainted(true);
pb.setForeground(Color.red);
pb.setBackground(Color.white);
b1.setBounds(20,20,80,25);pb.setBounds(110,20,200,25);
pb.setVisible(false);
add(b1);
add(pb);
b1.addActionListener(this);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e)
{
int i=0;
if(e.getSource()==b1)
{
pb.setVisible(true);
try
{
while(i<=100)
{
Thread.sleep(50);
pb.paintImmediately(0, 0, 200, 25);
pb.setValue(i);
i++;
}
}
catch(Exception e1)
{
System.out.print("Caughted exception is ="+e1);
}
}
}
public static void main(String arg[])
{
progressbardemo m=new progressbardemo();
m.setSize(330,100);
m.setVisible(true);
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - m.getWidth()) / 2);
int y = (int) ((dimension.getHeight() - m.getHeight()) / 2);
m.setLocation(x, y);
}
}

Categories

Resources