Java swing indeterminate JProgressBar starting from the left when reaching end instead of bouncing
I created a JProgressBar in a GUI application, and setted it to "indeterminate", but I don't like that it bounces instead of restarting every time it reaches the end. What can I do to fix this graphic setting?
java swing jprogressbar
add a comment |
I created a JProgressBar in a GUI application, and setted it to "indeterminate", but I don't like that it bounces instead of restarting every time it reaches the end. What can I do to fix this graphic setting?
java swing jprogressbar
add a comment |
I created a JProgressBar in a GUI application, and setted it to "indeterminate", but I don't like that it bounces instead of restarting every time it reaches the end. What can I do to fix this graphic setting?
java swing jprogressbar
I created a JProgressBar in a GUI application, and setted it to "indeterminate", but I don't like that it bounces instead of restarting every time it reaches the end. What can I do to fix this graphic setting?
java swing jprogressbar
java swing jprogressbar
asked Dec 28 '18 at 10:46
Prometal328Prometal328
206
206
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Change the UI of the JProgressBar.
The UI is the class that paints the progress bar. The BasicProgressBarUI, makes the box bounce by default. You just have to write your own class extending MetalProgressBarUI (if you're using Metal) and overriding getBox(Rectangle), which is the method that stores the position of the box in the given rectangle.
Use JProgressBar.setUI to apply the UI to your progress bar. You can also change the defaults with UIManager.put("ProgressBarUI", "fullyQualifiedClassName") to change the default UI for a progress bar.
Thanks a lot! So I can change the look and feel of evey element?
– Prometal328
Dec 28 '18 at 11:10
1
Use setUI on the JProgressBar to use your own UI. The L&F is defining default UIs, colors, borders, etc. that you can override.
– Snowy_1803
Dec 28 '18 at 11:13
I'm not understanding how to override it. Can you please write an example code where the rectangle remains still at the center of the progress bar? Sorry for bothering you too much...
– Prometal328
Dec 28 '18 at 13:34
r.x = componentsInnards.x + (int) Math.round(delta * numFrames/2)
– Snowy_1803
Dec 28 '18 at 14:02
Use getAnimationIndex() to get the current frame, and adapt if you want to support vertical progressbars.
– Snowy_1803
Dec 28 '18 at 14:04
|
show 4 more comments
As Snowy_1803 has already said, you would need to override the BasicProgressBarUI#getBox(...)
:
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.swing.*;
import javax.swing.plaf.basic.BasicProgressBarUI;
public final class MainPanel extends JPanel implements HierarchyListener {
private transient SwingWorker<String, Void> worker;
private MainPanel() {
super(new BorderLayout());
BoundedRangeModel model = new DefaultBoundedRangeModel();
JProgressBar progressBar = new JProgressBar(model) {
@Override public void updateUI() {
super.updateUI();
setUI(new OneDirectionProgressBarUI());
}
};
List<JProgressBar> list = Arrays.asList(new JProgressBar(model), progressBar);
JPanel p = new JPanel(new GridLayout(5, 1));
list.forEach(bar -> p.add(makePanel(bar)));
JButton button = new JButton("Test start");
button.addActionListener(e -> {
if (Objects.nonNull(worker) && !worker.isDone()) {
worker.cancel(true);
}
worker = new BackgroundTask();
list.forEach(bar -> {
bar.setIndeterminate(true);
worker.addPropertyChangeListener(new ProgressListener(bar));
});
worker.execute();
});
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.add(button);
box.add(Box.createHorizontalStrut(5));
addHierarchyListener(this);
add(p);
add(box, BorderLayout.SOUTH);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
}
@Override public void hierarchyChanged(HierarchyEvent e) {
boolean isDisplayableChanged = (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0;
if (isDisplayableChanged && !e.getComponent().isDisplayable() && Objects.nonNull(worker)) {
worker.cancel(true);
worker = null;
}
}
private static Component makePanel(Component cmp) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(5, 5, 5, 5);
c.weightx = 1d;
JPanel p = new JPanel(new GridBagLayout());
p.add(cmp, c);
return p;
}
public static void main(String args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new MainPanel());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class OneDirectionProgressBarUI extends BasicProgressBarUI {
@Override
protected Rectangle getBox(Rectangle r) {
Rectangle rect = super.getBox(r);
boolean vertical = progressBar.getOrientation() == JProgressBar.VERTICAL;
Insets ins = new Insets(0, 0, 0, 0); // progressBar.getInsets();
int currentFrame = getAnimationIndex();
int framecount = getFrameCount() / 2;
currentFrame = currentFrame % framecount;
// @see com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java
// this code adjusts the chunk size to properly account for the
// size and gap specified in the XP style. It also does it's own
// box placement for the chunk animation. This is required because
// the inherited algorithm from BasicProgressBarUI goes back and
// forth whereas XP only goes in one direction. XP also has ghosted
// trailing chunks to create the illusion of speed. This code
// adjusts the pixel length of the animation to account for the
// trails.
if (!vertical) {
rect.y = rect.y + ins.top;
rect.height = progressBar.getHeight() - ins.top - ins.bottom;
int len = progressBar.getWidth() - ins.left - ins.right;
len += rect.width * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.x = (int) (delta * currentFrame) + ins.left;
} else {
rect.x = rect.x + ins.left;
rect.width = progressBar.getWidth() - ins.left - ins.right;
int len = progressBar.getHeight() - ins.top - ins.bottom;
len += rect.height * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.y = (int) (delta * currentFrame) + ins.top;
}
return rect;
}
}
class BackgroundTask extends SwingWorker<String, Void> {
@Override public String doInBackground() {
try { // dummy task
Thread.sleep(5000);
} catch (InterruptedException ex) {
return "Interrupted";
}
int current = 0;
int lengthOfTask = 100;
while (current <= lengthOfTask && !isCancelled()) {
try { // dummy task
Thread.sleep(50);
} catch (InterruptedException ex) {
return "Interrupted";
}
setProgress(100 * current / lengthOfTask);
current++;
}
return "Done";
}
}
class ProgressListener implements PropertyChangeListener {
private final JProgressBar progressBar;
protected ProgressListener(JProgressBar progressBar) {
this.progressBar = progressBar;
this.progressBar.setValue(0);
}
@Override public void propertyChange(PropertyChangeEvent e) {
String strPropertyName = e.getPropertyName();
if ("progress".equals(strPropertyName)) {
progressBar.setIndeterminate(false);
int progress = (Integer) e.getNewValue();
progressBar.setValue(progress);
}
}
}
So I had to create the variables by myself! Thanks for your help too.
– Prometal328
Dec 28 '18 at 14:38
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53957264%2fjava-swing-indeterminate-jprogressbar-starting-from-the-left-when-reaching-end-i%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Change the UI of the JProgressBar.
The UI is the class that paints the progress bar. The BasicProgressBarUI, makes the box bounce by default. You just have to write your own class extending MetalProgressBarUI (if you're using Metal) and overriding getBox(Rectangle), which is the method that stores the position of the box in the given rectangle.
Use JProgressBar.setUI to apply the UI to your progress bar. You can also change the defaults with UIManager.put("ProgressBarUI", "fullyQualifiedClassName") to change the default UI for a progress bar.
Thanks a lot! So I can change the look and feel of evey element?
– Prometal328
Dec 28 '18 at 11:10
1
Use setUI on the JProgressBar to use your own UI. The L&F is defining default UIs, colors, borders, etc. that you can override.
– Snowy_1803
Dec 28 '18 at 11:13
I'm not understanding how to override it. Can you please write an example code where the rectangle remains still at the center of the progress bar? Sorry for bothering you too much...
– Prometal328
Dec 28 '18 at 13:34
r.x = componentsInnards.x + (int) Math.round(delta * numFrames/2)
– Snowy_1803
Dec 28 '18 at 14:02
Use getAnimationIndex() to get the current frame, and adapt if you want to support vertical progressbars.
– Snowy_1803
Dec 28 '18 at 14:04
|
show 4 more comments
Change the UI of the JProgressBar.
The UI is the class that paints the progress bar. The BasicProgressBarUI, makes the box bounce by default. You just have to write your own class extending MetalProgressBarUI (if you're using Metal) and overriding getBox(Rectangle), which is the method that stores the position of the box in the given rectangle.
Use JProgressBar.setUI to apply the UI to your progress bar. You can also change the defaults with UIManager.put("ProgressBarUI", "fullyQualifiedClassName") to change the default UI for a progress bar.
Thanks a lot! So I can change the look and feel of evey element?
– Prometal328
Dec 28 '18 at 11:10
1
Use setUI on the JProgressBar to use your own UI. The L&F is defining default UIs, colors, borders, etc. that you can override.
– Snowy_1803
Dec 28 '18 at 11:13
I'm not understanding how to override it. Can you please write an example code where the rectangle remains still at the center of the progress bar? Sorry for bothering you too much...
– Prometal328
Dec 28 '18 at 13:34
r.x = componentsInnards.x + (int) Math.round(delta * numFrames/2)
– Snowy_1803
Dec 28 '18 at 14:02
Use getAnimationIndex() to get the current frame, and adapt if you want to support vertical progressbars.
– Snowy_1803
Dec 28 '18 at 14:04
|
show 4 more comments
Change the UI of the JProgressBar.
The UI is the class that paints the progress bar. The BasicProgressBarUI, makes the box bounce by default. You just have to write your own class extending MetalProgressBarUI (if you're using Metal) and overriding getBox(Rectangle), which is the method that stores the position of the box in the given rectangle.
Use JProgressBar.setUI to apply the UI to your progress bar. You can also change the defaults with UIManager.put("ProgressBarUI", "fullyQualifiedClassName") to change the default UI for a progress bar.
Change the UI of the JProgressBar.
The UI is the class that paints the progress bar. The BasicProgressBarUI, makes the box bounce by default. You just have to write your own class extending MetalProgressBarUI (if you're using Metal) and overriding getBox(Rectangle), which is the method that stores the position of the box in the given rectangle.
Use JProgressBar.setUI to apply the UI to your progress bar. You can also change the defaults with UIManager.put("ProgressBarUI", "fullyQualifiedClassName") to change the default UI for a progress bar.
edited Dec 28 '18 at 13:39
answered Dec 28 '18 at 11:05
Snowy_1803Snowy_1803
120111
120111
Thanks a lot! So I can change the look and feel of evey element?
– Prometal328
Dec 28 '18 at 11:10
1
Use setUI on the JProgressBar to use your own UI. The L&F is defining default UIs, colors, borders, etc. that you can override.
– Snowy_1803
Dec 28 '18 at 11:13
I'm not understanding how to override it. Can you please write an example code where the rectangle remains still at the center of the progress bar? Sorry for bothering you too much...
– Prometal328
Dec 28 '18 at 13:34
r.x = componentsInnards.x + (int) Math.round(delta * numFrames/2)
– Snowy_1803
Dec 28 '18 at 14:02
Use getAnimationIndex() to get the current frame, and adapt if you want to support vertical progressbars.
– Snowy_1803
Dec 28 '18 at 14:04
|
show 4 more comments
Thanks a lot! So I can change the look and feel of evey element?
– Prometal328
Dec 28 '18 at 11:10
1
Use setUI on the JProgressBar to use your own UI. The L&F is defining default UIs, colors, borders, etc. that you can override.
– Snowy_1803
Dec 28 '18 at 11:13
I'm not understanding how to override it. Can you please write an example code where the rectangle remains still at the center of the progress bar? Sorry for bothering you too much...
– Prometal328
Dec 28 '18 at 13:34
r.x = componentsInnards.x + (int) Math.round(delta * numFrames/2)
– Snowy_1803
Dec 28 '18 at 14:02
Use getAnimationIndex() to get the current frame, and adapt if you want to support vertical progressbars.
– Snowy_1803
Dec 28 '18 at 14:04
Thanks a lot! So I can change the look and feel of evey element?
– Prometal328
Dec 28 '18 at 11:10
Thanks a lot! So I can change the look and feel of evey element?
– Prometal328
Dec 28 '18 at 11:10
1
1
Use setUI on the JProgressBar to use your own UI. The L&F is defining default UIs, colors, borders, etc. that you can override.
– Snowy_1803
Dec 28 '18 at 11:13
Use setUI on the JProgressBar to use your own UI. The L&F is defining default UIs, colors, borders, etc. that you can override.
– Snowy_1803
Dec 28 '18 at 11:13
I'm not understanding how to override it. Can you please write an example code where the rectangle remains still at the center of the progress bar? Sorry for bothering you too much...
– Prometal328
Dec 28 '18 at 13:34
I'm not understanding how to override it. Can you please write an example code where the rectangle remains still at the center of the progress bar? Sorry for bothering you too much...
– Prometal328
Dec 28 '18 at 13:34
r.x = componentsInnards.x + (int) Math.round(delta * numFrames/2)
– Snowy_1803
Dec 28 '18 at 14:02
r.x = componentsInnards.x + (int) Math.round(delta * numFrames/2)
– Snowy_1803
Dec 28 '18 at 14:02
Use getAnimationIndex() to get the current frame, and adapt if you want to support vertical progressbars.
– Snowy_1803
Dec 28 '18 at 14:04
Use getAnimationIndex() to get the current frame, and adapt if you want to support vertical progressbars.
– Snowy_1803
Dec 28 '18 at 14:04
|
show 4 more comments
As Snowy_1803 has already said, you would need to override the BasicProgressBarUI#getBox(...)
:
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.swing.*;
import javax.swing.plaf.basic.BasicProgressBarUI;
public final class MainPanel extends JPanel implements HierarchyListener {
private transient SwingWorker<String, Void> worker;
private MainPanel() {
super(new BorderLayout());
BoundedRangeModel model = new DefaultBoundedRangeModel();
JProgressBar progressBar = new JProgressBar(model) {
@Override public void updateUI() {
super.updateUI();
setUI(new OneDirectionProgressBarUI());
}
};
List<JProgressBar> list = Arrays.asList(new JProgressBar(model), progressBar);
JPanel p = new JPanel(new GridLayout(5, 1));
list.forEach(bar -> p.add(makePanel(bar)));
JButton button = new JButton("Test start");
button.addActionListener(e -> {
if (Objects.nonNull(worker) && !worker.isDone()) {
worker.cancel(true);
}
worker = new BackgroundTask();
list.forEach(bar -> {
bar.setIndeterminate(true);
worker.addPropertyChangeListener(new ProgressListener(bar));
});
worker.execute();
});
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.add(button);
box.add(Box.createHorizontalStrut(5));
addHierarchyListener(this);
add(p);
add(box, BorderLayout.SOUTH);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
}
@Override public void hierarchyChanged(HierarchyEvent e) {
boolean isDisplayableChanged = (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0;
if (isDisplayableChanged && !e.getComponent().isDisplayable() && Objects.nonNull(worker)) {
worker.cancel(true);
worker = null;
}
}
private static Component makePanel(Component cmp) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(5, 5, 5, 5);
c.weightx = 1d;
JPanel p = new JPanel(new GridBagLayout());
p.add(cmp, c);
return p;
}
public static void main(String args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new MainPanel());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class OneDirectionProgressBarUI extends BasicProgressBarUI {
@Override
protected Rectangle getBox(Rectangle r) {
Rectangle rect = super.getBox(r);
boolean vertical = progressBar.getOrientation() == JProgressBar.VERTICAL;
Insets ins = new Insets(0, 0, 0, 0); // progressBar.getInsets();
int currentFrame = getAnimationIndex();
int framecount = getFrameCount() / 2;
currentFrame = currentFrame % framecount;
// @see com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java
// this code adjusts the chunk size to properly account for the
// size and gap specified in the XP style. It also does it's own
// box placement for the chunk animation. This is required because
// the inherited algorithm from BasicProgressBarUI goes back and
// forth whereas XP only goes in one direction. XP also has ghosted
// trailing chunks to create the illusion of speed. This code
// adjusts the pixel length of the animation to account for the
// trails.
if (!vertical) {
rect.y = rect.y + ins.top;
rect.height = progressBar.getHeight() - ins.top - ins.bottom;
int len = progressBar.getWidth() - ins.left - ins.right;
len += rect.width * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.x = (int) (delta * currentFrame) + ins.left;
} else {
rect.x = rect.x + ins.left;
rect.width = progressBar.getWidth() - ins.left - ins.right;
int len = progressBar.getHeight() - ins.top - ins.bottom;
len += rect.height * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.y = (int) (delta * currentFrame) + ins.top;
}
return rect;
}
}
class BackgroundTask extends SwingWorker<String, Void> {
@Override public String doInBackground() {
try { // dummy task
Thread.sleep(5000);
} catch (InterruptedException ex) {
return "Interrupted";
}
int current = 0;
int lengthOfTask = 100;
while (current <= lengthOfTask && !isCancelled()) {
try { // dummy task
Thread.sleep(50);
} catch (InterruptedException ex) {
return "Interrupted";
}
setProgress(100 * current / lengthOfTask);
current++;
}
return "Done";
}
}
class ProgressListener implements PropertyChangeListener {
private final JProgressBar progressBar;
protected ProgressListener(JProgressBar progressBar) {
this.progressBar = progressBar;
this.progressBar.setValue(0);
}
@Override public void propertyChange(PropertyChangeEvent e) {
String strPropertyName = e.getPropertyName();
if ("progress".equals(strPropertyName)) {
progressBar.setIndeterminate(false);
int progress = (Integer) e.getNewValue();
progressBar.setValue(progress);
}
}
}
So I had to create the variables by myself! Thanks for your help too.
– Prometal328
Dec 28 '18 at 14:38
add a comment |
As Snowy_1803 has already said, you would need to override the BasicProgressBarUI#getBox(...)
:
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.swing.*;
import javax.swing.plaf.basic.BasicProgressBarUI;
public final class MainPanel extends JPanel implements HierarchyListener {
private transient SwingWorker<String, Void> worker;
private MainPanel() {
super(new BorderLayout());
BoundedRangeModel model = new DefaultBoundedRangeModel();
JProgressBar progressBar = new JProgressBar(model) {
@Override public void updateUI() {
super.updateUI();
setUI(new OneDirectionProgressBarUI());
}
};
List<JProgressBar> list = Arrays.asList(new JProgressBar(model), progressBar);
JPanel p = new JPanel(new GridLayout(5, 1));
list.forEach(bar -> p.add(makePanel(bar)));
JButton button = new JButton("Test start");
button.addActionListener(e -> {
if (Objects.nonNull(worker) && !worker.isDone()) {
worker.cancel(true);
}
worker = new BackgroundTask();
list.forEach(bar -> {
bar.setIndeterminate(true);
worker.addPropertyChangeListener(new ProgressListener(bar));
});
worker.execute();
});
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.add(button);
box.add(Box.createHorizontalStrut(5));
addHierarchyListener(this);
add(p);
add(box, BorderLayout.SOUTH);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
}
@Override public void hierarchyChanged(HierarchyEvent e) {
boolean isDisplayableChanged = (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0;
if (isDisplayableChanged && !e.getComponent().isDisplayable() && Objects.nonNull(worker)) {
worker.cancel(true);
worker = null;
}
}
private static Component makePanel(Component cmp) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(5, 5, 5, 5);
c.weightx = 1d;
JPanel p = new JPanel(new GridBagLayout());
p.add(cmp, c);
return p;
}
public static void main(String args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new MainPanel());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class OneDirectionProgressBarUI extends BasicProgressBarUI {
@Override
protected Rectangle getBox(Rectangle r) {
Rectangle rect = super.getBox(r);
boolean vertical = progressBar.getOrientation() == JProgressBar.VERTICAL;
Insets ins = new Insets(0, 0, 0, 0); // progressBar.getInsets();
int currentFrame = getAnimationIndex();
int framecount = getFrameCount() / 2;
currentFrame = currentFrame % framecount;
// @see com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java
// this code adjusts the chunk size to properly account for the
// size and gap specified in the XP style. It also does it's own
// box placement for the chunk animation. This is required because
// the inherited algorithm from BasicProgressBarUI goes back and
// forth whereas XP only goes in one direction. XP also has ghosted
// trailing chunks to create the illusion of speed. This code
// adjusts the pixel length of the animation to account for the
// trails.
if (!vertical) {
rect.y = rect.y + ins.top;
rect.height = progressBar.getHeight() - ins.top - ins.bottom;
int len = progressBar.getWidth() - ins.left - ins.right;
len += rect.width * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.x = (int) (delta * currentFrame) + ins.left;
} else {
rect.x = rect.x + ins.left;
rect.width = progressBar.getWidth() - ins.left - ins.right;
int len = progressBar.getHeight() - ins.top - ins.bottom;
len += rect.height * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.y = (int) (delta * currentFrame) + ins.top;
}
return rect;
}
}
class BackgroundTask extends SwingWorker<String, Void> {
@Override public String doInBackground() {
try { // dummy task
Thread.sleep(5000);
} catch (InterruptedException ex) {
return "Interrupted";
}
int current = 0;
int lengthOfTask = 100;
while (current <= lengthOfTask && !isCancelled()) {
try { // dummy task
Thread.sleep(50);
} catch (InterruptedException ex) {
return "Interrupted";
}
setProgress(100 * current / lengthOfTask);
current++;
}
return "Done";
}
}
class ProgressListener implements PropertyChangeListener {
private final JProgressBar progressBar;
protected ProgressListener(JProgressBar progressBar) {
this.progressBar = progressBar;
this.progressBar.setValue(0);
}
@Override public void propertyChange(PropertyChangeEvent e) {
String strPropertyName = e.getPropertyName();
if ("progress".equals(strPropertyName)) {
progressBar.setIndeterminate(false);
int progress = (Integer) e.getNewValue();
progressBar.setValue(progress);
}
}
}
So I had to create the variables by myself! Thanks for your help too.
– Prometal328
Dec 28 '18 at 14:38
add a comment |
As Snowy_1803 has already said, you would need to override the BasicProgressBarUI#getBox(...)
:
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.swing.*;
import javax.swing.plaf.basic.BasicProgressBarUI;
public final class MainPanel extends JPanel implements HierarchyListener {
private transient SwingWorker<String, Void> worker;
private MainPanel() {
super(new BorderLayout());
BoundedRangeModel model = new DefaultBoundedRangeModel();
JProgressBar progressBar = new JProgressBar(model) {
@Override public void updateUI() {
super.updateUI();
setUI(new OneDirectionProgressBarUI());
}
};
List<JProgressBar> list = Arrays.asList(new JProgressBar(model), progressBar);
JPanel p = new JPanel(new GridLayout(5, 1));
list.forEach(bar -> p.add(makePanel(bar)));
JButton button = new JButton("Test start");
button.addActionListener(e -> {
if (Objects.nonNull(worker) && !worker.isDone()) {
worker.cancel(true);
}
worker = new BackgroundTask();
list.forEach(bar -> {
bar.setIndeterminate(true);
worker.addPropertyChangeListener(new ProgressListener(bar));
});
worker.execute();
});
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.add(button);
box.add(Box.createHorizontalStrut(5));
addHierarchyListener(this);
add(p);
add(box, BorderLayout.SOUTH);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
}
@Override public void hierarchyChanged(HierarchyEvent e) {
boolean isDisplayableChanged = (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0;
if (isDisplayableChanged && !e.getComponent().isDisplayable() && Objects.nonNull(worker)) {
worker.cancel(true);
worker = null;
}
}
private static Component makePanel(Component cmp) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(5, 5, 5, 5);
c.weightx = 1d;
JPanel p = new JPanel(new GridBagLayout());
p.add(cmp, c);
return p;
}
public static void main(String args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new MainPanel());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class OneDirectionProgressBarUI extends BasicProgressBarUI {
@Override
protected Rectangle getBox(Rectangle r) {
Rectangle rect = super.getBox(r);
boolean vertical = progressBar.getOrientation() == JProgressBar.VERTICAL;
Insets ins = new Insets(0, 0, 0, 0); // progressBar.getInsets();
int currentFrame = getAnimationIndex();
int framecount = getFrameCount() / 2;
currentFrame = currentFrame % framecount;
// @see com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java
// this code adjusts the chunk size to properly account for the
// size and gap specified in the XP style. It also does it's own
// box placement for the chunk animation. This is required because
// the inherited algorithm from BasicProgressBarUI goes back and
// forth whereas XP only goes in one direction. XP also has ghosted
// trailing chunks to create the illusion of speed. This code
// adjusts the pixel length of the animation to account for the
// trails.
if (!vertical) {
rect.y = rect.y + ins.top;
rect.height = progressBar.getHeight() - ins.top - ins.bottom;
int len = progressBar.getWidth() - ins.left - ins.right;
len += rect.width * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.x = (int) (delta * currentFrame) + ins.left;
} else {
rect.x = rect.x + ins.left;
rect.width = progressBar.getWidth() - ins.left - ins.right;
int len = progressBar.getHeight() - ins.top - ins.bottom;
len += rect.height * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.y = (int) (delta * currentFrame) + ins.top;
}
return rect;
}
}
class BackgroundTask extends SwingWorker<String, Void> {
@Override public String doInBackground() {
try { // dummy task
Thread.sleep(5000);
} catch (InterruptedException ex) {
return "Interrupted";
}
int current = 0;
int lengthOfTask = 100;
while (current <= lengthOfTask && !isCancelled()) {
try { // dummy task
Thread.sleep(50);
} catch (InterruptedException ex) {
return "Interrupted";
}
setProgress(100 * current / lengthOfTask);
current++;
}
return "Done";
}
}
class ProgressListener implements PropertyChangeListener {
private final JProgressBar progressBar;
protected ProgressListener(JProgressBar progressBar) {
this.progressBar = progressBar;
this.progressBar.setValue(0);
}
@Override public void propertyChange(PropertyChangeEvent e) {
String strPropertyName = e.getPropertyName();
if ("progress".equals(strPropertyName)) {
progressBar.setIndeterminate(false);
int progress = (Integer) e.getNewValue();
progressBar.setValue(progress);
}
}
}
As Snowy_1803 has already said, you would need to override the BasicProgressBarUI#getBox(...)
:
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import javax.swing.*;
import javax.swing.plaf.basic.BasicProgressBarUI;
public final class MainPanel extends JPanel implements HierarchyListener {
private transient SwingWorker<String, Void> worker;
private MainPanel() {
super(new BorderLayout());
BoundedRangeModel model = new DefaultBoundedRangeModel();
JProgressBar progressBar = new JProgressBar(model) {
@Override public void updateUI() {
super.updateUI();
setUI(new OneDirectionProgressBarUI());
}
};
List<JProgressBar> list = Arrays.asList(new JProgressBar(model), progressBar);
JPanel p = new JPanel(new GridLayout(5, 1));
list.forEach(bar -> p.add(makePanel(bar)));
JButton button = new JButton("Test start");
button.addActionListener(e -> {
if (Objects.nonNull(worker) && !worker.isDone()) {
worker.cancel(true);
}
worker = new BackgroundTask();
list.forEach(bar -> {
bar.setIndeterminate(true);
worker.addPropertyChangeListener(new ProgressListener(bar));
});
worker.execute();
});
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.add(button);
box.add(Box.createHorizontalStrut(5));
addHierarchyListener(this);
add(p);
add(box, BorderLayout.SOUTH);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
}
@Override public void hierarchyChanged(HierarchyEvent e) {
boolean isDisplayableChanged = (e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0;
if (isDisplayableChanged && !e.getComponent().isDisplayable() && Objects.nonNull(worker)) {
worker.cancel(true);
worker = null;
}
}
private static Component makePanel(Component cmp) {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(5, 5, 5, 5);
c.weightx = 1d;
JPanel p = new JPanel(new GridBagLayout());
p.add(cmp, c);
return p;
}
public static void main(String args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new MainPanel());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class OneDirectionProgressBarUI extends BasicProgressBarUI {
@Override
protected Rectangle getBox(Rectangle r) {
Rectangle rect = super.getBox(r);
boolean vertical = progressBar.getOrientation() == JProgressBar.VERTICAL;
Insets ins = new Insets(0, 0, 0, 0); // progressBar.getInsets();
int currentFrame = getAnimationIndex();
int framecount = getFrameCount() / 2;
currentFrame = currentFrame % framecount;
// @see com/sun/java/swing/plaf/windows/WindowsProgressBarUI.java
// this code adjusts the chunk size to properly account for the
// size and gap specified in the XP style. It also does it's own
// box placement for the chunk animation. This is required because
// the inherited algorithm from BasicProgressBarUI goes back and
// forth whereas XP only goes in one direction. XP also has ghosted
// trailing chunks to create the illusion of speed. This code
// adjusts the pixel length of the animation to account for the
// trails.
if (!vertical) {
rect.y = rect.y + ins.top;
rect.height = progressBar.getHeight() - ins.top - ins.bottom;
int len = progressBar.getWidth() - ins.left - ins.right;
len += rect.width * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.x = (int) (delta * currentFrame) + ins.left;
} else {
rect.x = rect.x + ins.left;
rect.width = progressBar.getWidth() - ins.left - ins.right;
int len = progressBar.getHeight() - ins.top - ins.bottom;
len += rect.height * 2; // add 2x for the trails
double delta = (double) (len) / (double) framecount;
rect.y = (int) (delta * currentFrame) + ins.top;
}
return rect;
}
}
class BackgroundTask extends SwingWorker<String, Void> {
@Override public String doInBackground() {
try { // dummy task
Thread.sleep(5000);
} catch (InterruptedException ex) {
return "Interrupted";
}
int current = 0;
int lengthOfTask = 100;
while (current <= lengthOfTask && !isCancelled()) {
try { // dummy task
Thread.sleep(50);
} catch (InterruptedException ex) {
return "Interrupted";
}
setProgress(100 * current / lengthOfTask);
current++;
}
return "Done";
}
}
class ProgressListener implements PropertyChangeListener {
private final JProgressBar progressBar;
protected ProgressListener(JProgressBar progressBar) {
this.progressBar = progressBar;
this.progressBar.setValue(0);
}
@Override public void propertyChange(PropertyChangeEvent e) {
String strPropertyName = e.getPropertyName();
if ("progress".equals(strPropertyName)) {
progressBar.setIndeterminate(false);
int progress = (Integer) e.getNewValue();
progressBar.setValue(progress);
}
}
}
answered Dec 28 '18 at 14:19
ateraiaterai
8,40832439
8,40832439
So I had to create the variables by myself! Thanks for your help too.
– Prometal328
Dec 28 '18 at 14:38
add a comment |
So I had to create the variables by myself! Thanks for your help too.
– Prometal328
Dec 28 '18 at 14:38
So I had to create the variables by myself! Thanks for your help too.
– Prometal328
Dec 28 '18 at 14:38
So I had to create the variables by myself! Thanks for your help too.
– Prometal328
Dec 28 '18 at 14:38
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53957264%2fjava-swing-indeterminate-jprogressbar-starting-from-the-left-when-reaching-end-i%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown