After running my SWT application it doesn’t have any error at the time of compilation.
But after running it will shows the output for few sec and then the eclipse instance will become not responsive.
Please help me to avoid exceptions
I try to increase heap size.anybody is here to help me.....plzzzzzzzzzzzzzzzzzzzz
here i will give my code. i think my logic also have a problem. but i dont know how to correct it. i just follow on book to do this.here it is a program for clock. and i did in each movement of second hand a new thread is created. i want to make it as one thread.
it shows unable to create new native threads
activator.java
package com.packtpub.e4.clock.ui;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tray;
import org.eclipse.swt.widgets.TrayItem;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "com.packtpub.e4.clock.ui"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
private TrayItem trayItem;
private Image image;
private Shell shell;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
* #see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
final Display display = Display.getDefault();
display.asyncExec(new Runnable() {
public void run() {
image = new Image(display, Activator.class.getResourceAsStream("/icons/sample.gif"));
Tray tray = display.getSystemTray();
if (tray != null && image != null) {
trayItem = new TrayItem(tray, SWT.NONE);
trayItem.setToolTipText("Hello World");
trayItem.setVisible(true);
trayItem.setText("Hello World");
trayItem.setImage(new Image(trayItem.getDisplay(),
Activator.class.getResourceAsStream("/icons/sample.gif")));
}
trayItem.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
if (shell == null) {
shell = new Shell(trayItem.getDisplay());
shell.setLayout(new FillLayout());
new ClockWidget(shell, SWT.NONE, new RGB(255, 0, 255));
shell.pack();
}
shell.open();
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
}
});
}
/*
* (non-Javadoc)
* #see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
if (trayItem != null && !trayItem.isDisposed()) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (trayItem != null && !trayItem.isDisposed())
trayItem.dispose();
}
});
}
if (image != null && !image.isDisposed()) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (image != null && !image.isDisposed())
image.dispose();
}
});
}
if (shell != null && !shell.isDisposed()) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (shell != null && !shell.isDisposed())
shell.dispose();
}
});
}
}
/**
* Returns the shared instance
*
* #return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path
*
* #param path the path
* #return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}
clockwidget.java
package com.packtpub.e4.clock.ui;
import java.util.Date;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
public class ClockWidget extends Canvas
{
private final Color color;
private int offset;
public void setOffset(int offset)
{
this.offset = offset;
}
public Color getColor()
{
return color;
}
public int getOffset()
{
return offset;
}
public ClockWidget(Composite parent, int style,RGB rgb)
{
super(parent, style);
this.color = new Color(parent.getDisplay(),rgb);
addDisposeListener(new DisposeListener()
{
public void widgetDisposed(DisposeEvent e)
{
if(color != null && !color.isDisposed())
color.dispose();
}
});
addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
ClockWidget.this.paintControl(e);
}
});
}
public void paintControl(PaintEvent e)
{
#SuppressWarnings("deprecation")
int seconds = new Date().getSeconds();
int arc = (15-seconds) * 6 % 360;
e.gc.setBackground(color);
e.gc.fillArc(e.x,e.y,e.width-1,e.height-1,arc-1,2);
e.gc.drawArc(e.x,e.y,e.width-1,e.height-1,0,360);
e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_BLACK));
#SuppressWarnings("deprecation")
int hours = new Date().getHours() + offset;
arc = (3 - hours) * 30 % 360;
e.gc.fillArc(e.x, e.y, e.width-1, e.height-1, arc - 5, 10);
new Thread("TickTock")
{
public void run()
{
while (!ClockWidget.this.isDisposed())
{
ClockWidget.this.getDisplay().asyncExec(
new Runnable()
{
public void run()
{
if (!ClockWidget.this.isDisposed())
ClockWidget.this.redraw();
}
});
try
{
Thread.sleep(99999);
}
catch (InterruptedException e)
{
System.out.println("#clock"+e.toString());
return;
}
}
}
}.start();
}
public Point computeSize(int w,int h,boolean changed)
{
int size;
if(w == SWT.DEFAULT)
{
size = h;
}
else if (h == SWT.DEFAULT)
{
size = w;
}
else
{
size = Math.min(w,h);
}
if(size == SWT.DEFAULT)
size = 50;
return new Point(size,size);
}
}
SampleView.java
package com.packtpub.e4.clock.ui.views;
import java.util.TimeZone;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.*;
import org.eclipse.swt.SWT;
import com.packtpub.e4.clock.ui.ClockWidget;
public class SampleView extends ViewPart {
private Combo timezones;
public void createPartControl(Composite parent) {
try{
RowLayout layout = new RowLayout(SWT.HORIZONTAL);
parent.setLayout(layout);
Object[] oo=parent.getDisplay().getDeviceData().objects;
int c = 0;
for (int j = 0; j < oo.length; j++)
if (oo[j] instanceof Color)
c++;
System.err.println("There are " + c + " Color instances");
final ClockWidget clock1 =new ClockWidget(parent, SWT.NONE, new RGB(255,0,0));
//final ClockWidget clock2 =new ClockWidget(parent, SWT.NONE, new RGB(0,255,0));
//final ClockWidget clock3 =new ClockWidget(parent, SWT.NONE, new RGB(0,0,255));
//clock1.setLayoutData(new RowData(20,20));
//clock3.setLayoutData(new RowData(100,100));
String[] ids = TimeZone.getAvailableIDs();
timezones = new Combo(parent, SWT.SIMPLE);
timezones.setVisibleItemCount(5);
for (int i = 0; i < ids.length; i++) {
timezones.add(ids[i]);
timezones.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
String z = timezones.getText();
TimeZone tz = z == null ? null : TimeZone.getTimeZone(z);
TimeZone dt = TimeZone.getDefault();
int offset = tz == null ? 0 : (
tz.getOffset(System.currentTimeMillis()) -
dt.getOffset(System.currentTimeMillis())) / 3600000;
clock1.setOffset(offset);
clock1.redraw();
}
public void widgetDefaultSelected(SelectionEvent e) {
clock1.setOffset(0);
clock1.redraw();
}
});
}
}catch(Exception e){
System.out.println("# SampleView.java"+e.toString());
}
}
public void setFocus() {
timezones.setFocus();
}
}
i got the answer... here the thread call is happend in clockwidgets paintcontrol function cut it from there and paste it on clockwidget constructor.
then the code will work proper
package com.packtpub.e4.clock.ui;
import java.util.Date;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
public class ClockWidget extends Canvas
{
private final Color color;
private int offset;
public void setOffset(int offset)
{
this.offset = offset;
}
public Color getColor()
{
return color;
}
public int getOffset()
{
return offset;
}
public ClockWidget(Composite parent, int style,RGB rgb)
{
super(parent, style);
this.color = new Color(parent.getDisplay(),rgb);
addDisposeListener(new DisposeListener()
{
public void widgetDisposed(DisposeEvent e)
{
if(color != null && !color.isDisposed())
color.dispose();
}
});
new Thread("TickTock")
{
public void run()
{
while (!ClockWidget.this.isDisposed())
{
ClockWidget.this.getDisplay().asyncExec(
new Runnable()
{
public void run()
{
if (!ClockWidget.this.isDisposed())
ClockWidget.this.redraw();
}
});
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
return;
}
}
}
}.start();
addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
ClockWidget.this.paintControl(e);
}
});
}
public void paintControl(PaintEvent e)
{
#SuppressWarnings("deprecation")
int seconds = new Date().getSeconds();
int arc = (15-seconds) * 6 % 360;
e.gc.setBackground(color);
e.gc.fillArc(e.x,e.y,e.width-1,e.height-1,arc-1,2);
e.gc.drawArc(e.x,e.y,e.width-1,e.height-1,0,360);
e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_BLACK));
#SuppressWarnings("deprecation")
int hours = new Date().getHours() + offset;
arc = (3 - hours) * 30 % 360;
e.gc.fillArc(e.x, e.y, e.width-1, e.height-1, arc - 5, 10);
}
public Point computeSize(int w,int h,boolean changed)
{
int size;
if(w == SWT.DEFAULT)
{
size = h;
}
else if (h == SWT.DEFAULT)
{
size = w;
}
else
{
size = Math.min(w,h);
}
if(size == SWT.DEFAULT)
size = 50;
return new Point(size,size);
}
}
Related
I wanted to make a Glass Panel that contain a JPanel with white background, border and the msg "please wait".
Here is the code example:
JLabel glassLabel = new JLabel("Please wait");
FadingPanel msg = new FadingPanel();
glassLabel.setFont(new Font("Dialog", Font.BOLD, 26));
msg.setLayout(new BorderLayout());
msg.add(glassLabel,BorderLayout.NORTH);
msg.setBackground(Color.white);
msg.setFont(UIManager.getFont("Table.font").deriveFont(24f));
msg.setBorder(new CompoundBorder(new TitledBorder(""),
new EmptyBorder(20,20,20,20)));
It will fade in and out while waiting for the query.
the problem is that I am getting a bad result.
need help
the other is that none of them show it with glass panel
Animating the opacity state of a glassPane is no different from animating the state of any Swing component, after all, the glassPane is just another component.
one is that the Timer system doesn't know if the start function started and it keeps the panel hanging on because it closing it before fading the panel and then before it shows it and then it dont try to close it again
This is more about your own internal state management. The panel shouldn't care, it should just be responding to the request to change opacity level, forward or backwards
What you should have, is some kind of "engine" which can provide events when certain states are achieved, at which time, you make decisions about what should be done, removing the functionality from the "panel" itself.
Theory TL;DR
Okay, first, some theory.
Animation...
Animation is the illusion of change over time. In your case, you're moving from 0 to 1 and back again over a specified period of time. This is commonly known as "linear progression/animation". Most naive animation implementations will simple add a constant delta to a value and keep doing so until a desired state is reached. This is naive because not all systems are equal. Some will be able to achieve the desired state faster than others, making the animation uneven and providing a poor user experience.
Instead, you should be focused on perform a operation over a fixed period of time, calculating the required value as fast as the system will allow. This allows the animation to "drop" frames as required based on the system's capabilities. This is commonly known as "duration based animation".
This approach is much more powerful, as it allows you to play around with the speed of the animation in a very simply way. It also allows you do some very advanced operations, like easement, which wouldn't be easily achievable through a linear progression.
Swing and animation...
Swing is SINGLE threaded. This means you can't perform blocking or long running operations within the context of the Event Dispatching Thread.
Swing is also NOT thread safe. This means you shouldn't update the UI (or any state the UI depends on) from outside the context of the EDT.
For animation, what you need is some way to post, fast, repetitive, events onto the EDT, which will allow you to make changes to the UI safely. For this, the most common tool is a Swing Timer...
The Framework
So based on that, what we need is some kind of "engine", which given a "range" and a "duration" can notify us of "ticks" on a regular bases from which we can calculate the progression that the animation has played, and calculate the value we should use based on our inputs ... simple ...
I, personally, prefer to use an animation library, but the simple framework presented in the examples basically abstracts all these concepts into a re-usable framework.
Make it so...
nb: I ran out of room, so the underlying framework is included in the main example
Okay, that's all nice and fluffy, but how does this actually help us. Essentially, the idea of the above is to abstract common functionality out and make it re-usable (and yes, I actually do use it, a lot)
What we now need, is a component which can actually use it, something like...
public interface FaderListener {
public void fadeDidComplete(FadePane pane);
}
public class FadePane extends JPanel {
private double alpha = 1;
private boolean fadingIn = true;
private DoubleAnimatable animatable;
private Duration duration = Duration.ofSeconds(5);
private List<FaderListener> listeners = new ArrayList<>(5);
public FadePane() {
setOpaque(false);
}
public void addFadeListener(FaderListener listener) {
listeners.add(listener);
}
public void removeFadeListener(FaderListener listener) {
listeners.remove(listener);
}
public boolean isFadingIn() {
return fadingIn;
}
public double getAlpha() {
return alpha;
}
#Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive((float)getAlpha()));
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
super.paint(g2d);
g2d.dispose();
}
protected void fadeTo(double to) {
double currentAlpha = getAlpha();
if (animatable != null) {
animatable.stop();
animatable = null;
}
if (currentAlpha == to) {
fadeDidComplete();
return;
}
DoubleRange animationRange = new DoubleRange(currentAlpha, to);
double maxFrom = to == 1 ? 1 : 0;
double maxTo = to == 1 ? 0 : 1;
DoubleRange maxRange = new DoubleRange(maxFrom, maxTo);
animatable = new DoubleAnimatable(animationRange, maxRange, duration, new AnimatableListener<Double>() {
#Override
public void animationChanged(Animatable<Double> animatable) {
alpha = animatable.getValue();
repaint();
}
}, new AnimatableLifeCycleListenerAdapter<Double>() {
#Override
public void animationCompleted(Animatable<Double> animatable) {
fadeDidComplete();
}
});
Animator.INSTANCE.add(animatable);
}
public void fadeIn() {
fadingIn = true;
fadeTo(1);
}
public void fadeOut() {
fadingIn = false;
fadeTo(0);
}
protected void fadeDidComplete() {
for (FaderListener listener : listeners) {
listener.fadeDidComplete(this);
}
}
}
Okay, this is a pretty simple concept. It's a JPanel which has a alpha property which changes the opacity level of the component - basically, this is all faked, as Swing only support opaque and transparent components, not translucent components. So we set the component to be transparent and manually paint the background ourselves.
The component exposes two methods, fadeIn and fadeOut and supports a FaderListener which can be used to notify interested parties that the fade operation has been completed
Runnable example...
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBackground(Color.RED);
setLayout(new BorderLayout());
FadePane pane = new FadePane();
pane.setLayout(new GridBagLayout());
pane.add(new JLabel("Look ma, no hands"));
add(pane);
JButton btn = new JButton("Switch");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
btn.setEnabled(false);
if (pane.isFadingIn()) {
pane.fadeOut();
} else {
pane.fadeIn();
}
}
});
add(btn, BorderLayout.SOUTH);
pane.addFadeListener(new FaderListener() {
#Override
public void fadeDidComplete(FadePane pane) {
btn.setEnabled(true);
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public interface FaderListener {
public void fadeDidComplete(FadePane pane);
}
public class FadePane extends JPanel {
private double alpha = 1;
private boolean fadingIn = true;
private DoubleAnimatable animatable;
private Duration duration = Duration.ofSeconds(5);
private List<FaderListener> listeners = new ArrayList<>(5);
public FadePane() {
setOpaque(false);
}
public void addFadeListener(FaderListener listener) {
listeners.add(listener);
}
public void removeFadeListener(FaderListener listener) {
listeners.remove(listener);
}
public boolean isFadingIn() {
return fadingIn;
}
public double getAlpha() {
return alpha;
}
public void setFaddedOut() {
alpha = 0;
fadingIn = false;
}
public void setFaddedIn() {
alpha = 1;
fadingIn = true;
}
#Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive((float)getAlpha()));
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
super.paint(g2d);
g2d.dispose();
}
protected void fadeTo(double to) {
double currentAlpha = getAlpha();
if (animatable != null) {
animatable.stop();
animatable = null;
}
if (currentAlpha == to) {
fadeDidComplete();
return;
}
DoubleRange animationRange = new DoubleRange(currentAlpha, to);
double maxFrom = to == 1 ? 1 : 0;
double maxTo = to == 1 ? 0 : 1;
DoubleRange maxRange = new DoubleRange(maxFrom, maxTo);
animatable = new DoubleAnimatable(animationRange, maxRange, duration, new AnimatableListener<Double>() {
#Override
public void animationChanged(Animatable<Double> animatable) {
alpha = animatable.getValue();
repaint();
}
}, new AnimatableLifeCycleListenerAdapter<Double>() {
#Override
public void animationCompleted(Animatable<Double> animatable) {
fadeDidComplete();
}
});
Animator.INSTANCE.add(animatable);
}
public void fadeIn() {
fadingIn = true;
fadeTo(1);
}
public void fadeOut() {
fadingIn = false;
fadeTo(0);
}
protected void fadeDidComplete() {
for (FaderListener listener : listeners) {
listener.fadeDidComplete(this);
}
}
}
public class DoubleAnimatable extends AbstractAnimatable<Double> {
public DoubleAnimatable(DoubleRange animationRange, DoubleRange maxRange, Duration duration, AnimatableListener<Double> listener, AnimatableLifeCycleListener<Double> lifeCycleListener) {
super(animationRange, duration, listener, lifeCycleListener);
double maxDistance = maxRange.getDistance();
double aniDistance = animationRange.getDistance();
double progress = Math.min(100, Math.max(0, Math.abs(aniDistance / maxDistance)));
Duration remainingDuration = Duration.ofMillis((long) (duration.toMillis() * progress));
setDuration(remainingDuration);
}
}
public interface AnimatableListener<T> {
public void animationChanged(Animatable<T> animatable);
}
public interface AnimatableLifeCycleListener<T> {
public void animationStopped(Animatable<T> animatable);
public void animationCompleted(Animatable<T> animatable);
public void animationStarted(Animatable<T> animatable);
public void animationPaused(Animatable<T> animatable);
}
public class AnimatableLifeCycleListenerAdapter<T> implements AnimatableLifeCycleListener<T> {
#Override
public void animationStopped(Animatable<T> animatable) {
}
#Override
public void animationCompleted(Animatable<T> animatable) {
}
#Override
public void animationStarted(Animatable<T> animatable) {
}
#Override
public void animationPaused(Animatable<T> animatable) {
}
}
public abstract class AbstractAnimatable<T> implements Animatable<T> {
private Range<T> range;
private LocalDateTime startTime;
private Duration duration = Duration.ofSeconds(5);
private T value;
private AnimatableListener<T> animatableListener;
private AnimatableLifeCycleListener<T> lifeCycleListener;
// private Easement easement;
private double rawOffset;
public AbstractAnimatable(Range<T> range, Duration duration, AnimatableListener<T> listener) {
this.range = range;
this.value = range.getFrom();
this.animatableListener = listener;
}
public AbstractAnimatable(Range<T> range, Duration duration, AnimatableListener<T> listener, AnimatableLifeCycleListener<T> lifeCycleListener) {
this(range, duration, listener);
this.lifeCycleListener = lifeCycleListener;
}
// public AbstractAnimatable(Range<T> range, Duration duration, Easement easement, AnimatableListener<T> listener) {
// this(range, duration, listener);
// this.easement = easement;
// }
//
// public AbstractAnimatable(Range<T> range, Duration duration, Easement easement, AnimatableListener<T> listener, AnimatableLifeCycleListener<T> lifeCycleListener) {
// this(range, duration, easement, listener);
// this.lifeCycleListener = lifeCycleListener;
// }
//
// public void setEasement(Easement easement) {
// this.easement = easement;
// }
//
// #Override
// public Easement getEasement() {
// return easement;
// }
public Duration getDuration() {
return duration;
}
public Range<T> getRange() {
return range;
}
public void setRange(Range<T> range) {
this.range = range;
}
#Override
public T getValue() {
return value;
}
protected void setDuration(Duration duration) {
this.duration = duration;
}
public double getCurrentProgress(double rawProgress) {
double progress = Math.min(1.0, Math.max(0.0, getRawProgress()));
// Easement easement = getEasement();
// if (easement != null) {
// progress = easement.interpolate(progress);
// }
return Math.min(1.0, Math.max(0.0, progress));
}
public double getRawProgress() {
if (startTime == null) {
return 0.0;
}
Duration duration = getDuration();
Duration runningTime = Duration.between(startTime, LocalDateTime.now());
double progress = rawOffset + (runningTime.toMillis() / (double) duration.toMillis());
return Math.min(1.0, Math.max(0.0, progress));
}
#Override
public void tick() {
if (startTime == null) {
startTime = LocalDateTime.now();
fireAnimationStarted();
}
double rawProgress = getRawProgress();
double progress = getCurrentProgress(rawProgress);
if (rawProgress >= 1.0) {
progress = 1.0;
}
value = getRange().valueAt(progress);
fireAnimationChanged();
if (rawProgress >= 1.0) {
fireAnimationCompleted();
}
}
#Override
public void start() {
if (startTime != null) {
// Restart?
return;
}
Animator.INSTANCE.add(this);
}
#Override
public void stop() {
stopWithNotification(true);
}
#Override
public void pause() {
rawOffset += getRawProgress();
stopWithNotification(false);
double remainingProgress = 1.0 - rawOffset;
Duration remainingTime = getDuration().minusMillis((long) remainingProgress);
setDuration(remainingTime);
lifeCycleListener.animationStopped(this);
}
protected void fireAnimationChanged() {
if (animatableListener == null) {
return;
}
animatableListener.animationChanged(this);
}
protected void fireAnimationCompleted() {
stopWithNotification(false);
if (lifeCycleListener == null) {
return;
}
lifeCycleListener.animationCompleted(this);
}
protected void fireAnimationStarted() {
if (lifeCycleListener == null) {
return;
}
lifeCycleListener.animationStarted(this);
}
protected void fireAnimationPaused() {
if (lifeCycleListener == null) {
return;
}
lifeCycleListener.animationPaused(this);
}
protected void stopWithNotification(boolean notify) {
Animator.INSTANCE.remove(this);
startTime = null;
if (notify) {
if (lifeCycleListener == null) {
return;
}
lifeCycleListener.animationStopped(this);
}
}
}
public interface Animatable<T> {
public Range<T> getRange();
public T getValue();
public void tick();
public Duration getDuration();
//public Easement getEasement();
// Wondering if these should be part of a secondary interface
// Provide a "self managed" unit of work
public void start();
public void stop();
public void pause();
}
public abstract class Range<T> {
private T from;
private T to;
public Range(T from, T to) {
this.from = from;
this.to = to;
}
public T getFrom() {
return from;
}
public T getTo() {
return to;
}
#Override
public String toString() {
return "From " + getFrom() + " to " + getTo();
}
public abstract T valueAt(double progress);
}
public class DoubleRange extends Range<Double> {
public DoubleRange(Double from, Double to) {
super(from, to);
}
public Double getDistance() {
return getTo() - getFrom();
}
#Override
public Double valueAt(double progress) {
double distance = getDistance();
double value = distance * progress;
value += getFrom();
return value;
}
}
public enum Animator {
INSTANCE;
private Timer timer;
private List<Animatable> properies;
private Animator() {
properies = new ArrayList<>(5);
timer = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
List<Animatable> copy = new ArrayList<>(properies);
Iterator<Animatable> it = copy.iterator();
while (it.hasNext()) {
Animatable ap = it.next();
ap.tick();
}
if (properies.isEmpty()) {
timer.stop();
}
}
});
}
public void add(Animatable ap) {
properies.add(ap);
timer.start();
}
protected void removeAll(List<Animatable> completed) {
properies.removeAll(completed);
}
public void remove(Animatable ap) {
properies.remove(ap);
if (properies.isEmpty()) {
timer.stop();
}
}
}
}
But it's not a glassPane
... ok, as I said, a glassPane is just another component
This is a simple example which makes use of the frame's glassPane and will, when the panel is faded out, reset the glassPane to a default component
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JButton btn = new JButton("Switch");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window window = SwingUtilities.getWindowAncestor(TestPane.this);
if (!(window instanceof JFrame)) {
System.out.println("Not out frame");
return;
}
JFrame frame = (JFrame) window;
FadePane pane = new FadePane();
pane.setLayout(new BorderLayout());
pane.add(new JLabel("All your base are belong to us"));
pane.setFaddedOut();
pane.addFadeListener(new FaderListener() {
#Override
public void fadeDidComplete(FadePane pane) {
System.out.println("Completed");
if (pane.getAlpha() == 1) {
System.out.println("Fade out");
pane.fadeOut();
} else {
System.out.println("Remove glasspane");
frame.setGlassPane(new JPanel());
}
}
});
frame.setGlassPane(pane);
System.out.println("Fade in");
pane.setVisible(true);
pane.fadeIn();
}
});
add(btn);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
nb: The required classes are in the previous example
Consider using JDialog container. When it is undecorated, you can change its opacity:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.WindowConstants;
public class FadeDialog extends JDialog {
private float alfa = 1;
private JLabel label;
private boolean isFadeIn = true;
private JButton fadeIn, fadeOut;
FadeDialog() {
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setLocation(new Point(300, 300));
getContentPane().setLayout(new BorderLayout(5,0));
setUndecorated(true); //opacity supported for undecorated JDialogs
JButton close = new JButton("Close");
close.addActionListener(e -> dispose());
getContentPane().add(close, BorderLayout.PAGE_END);
getContentPane().add(new ContentPane(), BorderLayout.CENTER);
pack();
setVisible(true);
Timer timer = new Timer(2000, e -> fade());//endless fade-in-out loop
timer.setInitialDelay(100);
timer.start();
}
void fade() {
alfa = isFadeIn ? alfa + 0.1f : alfa -0.1f;
if(alfa <=0 ) {
alfa = 0; isFadeIn = true;
}else if(alfa >= 1) {
alfa = 1; isFadeIn = false;
}
fadeIn.setEnabled(! isFadeIn); fadeOut.setEnabled(isFadeIn);
label.setText("Alfa is " + alfa);
setOpacity(alfa); //set JDialog opacity
}
class ContentPane extends JPanel {
ContentPane() {
setPreferredSize(new Dimension(200, 100));
setLayout(new BorderLayout());
fadeIn = new JButton("Fade In");
fadeIn.addActionListener(e -> isFadeIn = true);
add(fadeIn, BorderLayout.PAGE_START);
label = new JLabel("Alfa is " + alfa);
add(label, BorderLayout.CENTER);
fadeOut = new JButton("Fade Out");
fadeOut.addActionListener(e -> isFadeIn = false);
add(fadeOut, BorderLayout.PAGE_END);
}
}
public static void main(String[] args) {
new FadeDialog();
}
}
package finalproje;
import java.awt.Color;
import java.awt.MouseInfo;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.Timer;
class GUIMover {
private ArrayList<JFrame> frameList = new ArrayList<JFrame>();
private int count, max, matchNumber;
private Random random = new Random();
private Timer update;
private boolean matchFound = false;
long startTime = System.currentTimeMillis();
public GUIMover(int max) {
this.max = max;
matchNumber = random.nextInt(max);
update = new Timer(500, updateAction);
update.setCoalesce(true);
}
public void startGUI() {
JOptionPane.showMessageDialog(null, "Find window " + matchNumber);
for (; count < max;) {
final JFrame frame = new JFrame(count + "");
++count;
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);// exits
// windows
// when
// closed.
frame.setVisible(true);
frame.setBackground(new Color(random.nextFloat(), random
.nextFloat(), random.nextFloat()));
frame.setBounds(random.nextInt(500), random.nextInt(500),
random.nextInt(500), random.nextInt(500));
frame.addMouseListener(new MouseListener() {
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
// check if you clicked your match
public void mouseClicked(MouseEvent e)
throws NumberFormatException {
if (!matchFound
&& Integer.parseInt(frame.getTitle()) == matchNumber) {
matchFound = true;
frameList.get(0).setTitle(
"You won after " + getPrintableGameTime()/*
* conversion
* from
* milliseconds
* to
* seconds
*/
+ " seconds!");
for (int q = frameList.size() - 1; q > 0; q--) {
frameList.get(q).dispose();
}
frameList.get(0).setSize(500, 500);
}
}
});
frameList.add(frame);
}
update.start();
}
boolean hasIntersections(JFrame f) {
for (JFrame x : frameList)
if (f != x && f.getBounds().intersects(x.getBounds())) {
return true;
}
return false;
}
String getPrintableGameTime() {
if (matchFound) {
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
return String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toSeconds(totalTime) / 60,
TimeUnit.MILLISECONDS.toSeconds(totalTime) % 60);
} else
return "You shouldn't see this.";
}
#SuppressWarnings("serial")
/* serves as update method */
Action updateAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
if (!matchFound) {
for (JFrame i : frameList) {
i.setLocation(
(MouseInfo.getPointerInfo().getLocation().x + random
.nextInt(1000)), (MouseInfo
.getPointerInfo().getLocation().y + random
.nextInt(1000)));
i.setLocation(random.nextInt(900), random.nextInt(800));
}
for (int j = 0; j < frameList.size(); j++) {
while (hasIntersections(frameList.get(j))) {
frameList.get(j).setLocation(
frameList.get(j).getX() + 10,
frameList.get(j).getY());
if (frameList.get(j).getX() > 1200) {
frameList.get(j).setLocation(0,
frameList.get(j).getY() + 100);
frameList.get(j).setSize(
frameList.get(j).getWidth() - 10,
frameList.get(j).getHeight() - 10);
} else if (frameList.get(j).getY() > 800) {
frameList.get(j).setSize(
frameList.get(j).getWidth() - 10,
frameList.get(j).getHeight() - 10);
frameList.get(j).setLocation(0,
frameList.get(j).getX() + 100);
}
}
}
}
}
};
}
Is it possible to separate the thread which the mouse listener listens on?
While the GUI is moving, any input is ignored, which is very frustrating because this includes the clicking of the close button (red x), which would require me to SIGKILL the process.
Invoke javax.swing.Timer#start() same time,
7u25 is not problem.
but 7u40 is big problem.
Too laggy invoke ActionListener#actionPerformed. (basically same time invoke u25)
Totally different move between u25 and u40. (I use Windows 8)
I bug report but still not add bug tracking system. Oracle crushing swing apps?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimerProblem extends JComponent {
int red = 0;
TimerProblem(final long startMs) {
setPreferredSize(new Dimension(10, 10));
Timer t = new Timer(16, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
red = (int)(System.currentTimeMillis() - startMs) % 255;
repaint();
}
});
t.setInitialDelay(1000);
t.start();
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(new Color(red, 255 - red, 0));
g.fillRect(0, 0, getWidth(), getHeight());
}
public static void main(String[] args) {
JFrame f = new JFrame();
Container c = f.getContentPane();
c.setLayout(new GridLayout(10, 10));
long startMs = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
c.add(new TimerProblem(startMs));
}
f.pack();
f.setVisible(true);
}
}
Several issues arise in your example:
Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
All Swing Timer instances share a common thread, which is being saturated.
Depending on the goal, some alternatives are possible:
Use a single Timer instance, and select some fraction for update at a proportionally higher rate. The example below randomly selects N of the components and updates them every 100 ms.
Use TexturePaint, as shown here.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javax.swing.*;
/** #see https://stackoverflow.com/a/18936444/230513 */
public class BlinkenLights {
private static final int S = 24;
private static final int N = 10;
private static final Random r = new Random();
private static final List<MyComponent> list = new ArrayList<MyComponent>();
private static final class MyComponent extends JComponent {
public MyComponent() {
this.setOpaque(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(S, S);
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(Color.getHSBColor(r.nextFloat() / 6, 1, 1));
g.fillRect(0, 0, getWidth(), getHeight());
}
}
private static JPanel createPanel() {
final JPanel p = new JPanel();
p.setLayout(new GridLayout(N, N));
for (int i = 0; i < N * N; i++) {
MyComponent c = new MyComponent();
p.add(c);
list.add(c);
}
Timer t = new Timer(1000 / N, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Collections.shuffle(list, r);
for (int i = 0; i < N; i++) {
list.get(i).repaint();
}
}
});
t.start();
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(createPanel());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
Finally I write DIY repaint management class .. :(
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
/**
* EffectTimer
*/
public class EffectTimer {
/**
* All of effect timers in instance of this class.
*/
static class GlobalTimer implements ActionListener {
List<EffectTimer> registeredEffects = new ArrayList<>();
Timer timer = new Timer(16, this);
public void start(final EffectTimer t) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
internalStart(t);
}
});
}
void internalStart(EffectTimer t) {
int initialDelay = Math.max(0, (int) (t.getEffectStartTime() - System.currentTimeMillis()));
if(timer.getInitialDelay() >= initialDelay) {
timer.setInitialDelay(initialDelay);
}
if(!registeredEffects.contains(t)) {
registeredEffects.add(t);
if(registeredEffects.size() == 1) {
timer.start();
}
}
}
void stop(final EffectTimer t) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
registeredEffects.remove(t);
checkStop();
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
long now = e.getWhen();
Iterator<EffectTimer> iter = registeredEffects.iterator();
while(iter.hasNext()) {
EffectTimer t = iter.next();
long elapsedMs = now - t.getEffectStartTime();
if(elapsedMs > 0) {
float p = elapsedMs / (float)t.getEffectLengthMs();
if(p >= 1.0f) {
iter.remove();
t.stop();
} else {
if(t.isReversed()) {
p = 1.0f - p;
}
t.progressChanged(p);
}
}
}
checkStop();
}
void checkStop() {
if(registeredEffects.isEmpty()) {
timer.stop();
}
}
public int getRunningTimerCount() {
return registeredEffects.size();
}
public void stopAll() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
registeredEffects.clear();
checkStop();
}
});
}
}
static final GlobalTimer GTIMER = new GlobalTimer();
int effectLengthMs = -1;
long effectStartMs = -1;
float progress = 0.0f;
boolean reversed = true;
public long getEffectStartTime() {
return effectStartMs;
}
public int getEffectLengthMs() {
return effectLengthMs;
}
public void start(int lengthMs) {
start(lengthMs, System.currentTimeMillis());
}
public void start(int lengthMs, long startMs) {
effectLengthMs = lengthMs;
effectStartMs = startMs;
reversed = false;
progress = 0.0f;
GTIMER.start(this);
}
public boolean isReversed() {
return reversed;
}
public void reverse(final int lengthMs) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
internalReverse(lengthMs);
}
});
}
void internalReverse(int lengthMs) {
reversed = !reversed;
effectLengthMs = lengthMs;
int adjust = reversed ? (int)(lengthMs * (1.0f - progress)) : (int)(lengthMs * progress);
effectStartMs = System.currentTimeMillis() - adjust;
GTIMER.start(this);
}
final public void progressChanged(float p) {
progress = p;
run(p);
}
/**
* 0.0f to 1.0f effect progress.
* <code>Float.compare(progress, 1.0f) >= 0</code> to end progress.
*/
protected void run(float p) {}
public void stop() {
progress = reversed ? 0.0f : 1.0f;
GTIMER.stop(this);
}
public boolean isRunning() {
return 0.0f < progress && progress < 1.0f;
}
public float getProgress() {
return progress;
}
public static int getRunningTimerCount() {
return GTIMER.getRunningTimerCount();
}
public static void stopAll() {
GTIMER.stopAll();
}
}
So I have an interesting problem. I have an application that I wanted to have progress bars in each cell of the table. To be safe I wrote a stand alone app that does just what I want but now I'm having problems incorporating it into my pre-existing code. Im getting lost on what I need from each file. I.m posting the app table and the progress bar table code. I need to get these two two mesh or to puot it simply I need the progress bar in the app table. Any help appreciated.
application table
package gui;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AlgorithmParameters;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class FileTable extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTable table;
private DefaultTableModel tableModel =
new DefaultTableModel(new String[]
{"File", "Size", "Status" }, 0);
private File dir;
private File temp;
private JPopupMenu popup;
private String key;
private PasswordStorage passwordStorage;
private JFileChooser fileChooser;
private static String salt = "loquetdeliciouslysalty";
private static byte[] IV;
public FileTable() {
// Set Layout Manager
setLayout(new BorderLayout());
// Create Swing Components
table = new JTable();
table.setModel(tableModel);
table.setDropTarget(new TableDnD(table));
table.setShowGrid(false);
table.setFillsViewportHeight(true);
table.getColumnModel().getColumn(0).setPreferredWidth(250);
passwordStorage = new PasswordStorage();
fileChooser = new JFileChooser();
popup = new JPopupMenu();
JMenuItem removeItem = new JMenuItem("Remove");
removeItem.setIcon(new ImageIcon("removeMenu.png"));
popup.add(removeItem);
// Add Components to pane
add(new JScrollPane(table), BorderLayout.CENTER);
table.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int row = table.rowAtPoint(e.getPoint());
table.getSelectionModel().setSelectionInterval(row, row);
if(e.getButton() == MouseEvent.BUTTON3) {
popup.show(table, e.getX(), e.getY());
}
}
});
removeItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int row = table.getSelectedRow();
if(row > -1) {
tableModel.removeRow(table.getSelectedRow());
}
}
});
}
public boolean isTableEmpty() {
if(tableModel.getRowCount() == 0) {
return true;
}
else {
return false;
}
}
public void addFile(File file) {
tableModel.addRow(
new Object[]{file, file.length() + " kb",Not Processed"});
}
public void removeFile() {
int[] rows = table.getSelectedRows();
for(int i = 0; i < rows.length; i++) {
tableModel.removeRow(rows[i]-i);
}
}
public void clearTable()
{
int rowCount = tableModel.getRowCount();
for(int i = 0; i < rowCount; i++) {
tableModel.removeRow(0);
}
table.removeAll();
}
}
The progress bar table
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
public class UpdateTable
{
public static void main(String[] args)
{
new UpdateTable();
}
public UpdateTable()
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException |
InstantiationException | IllegalAccessException |
UnsupportedLookAndFeelException ex) {
}
UpdatableTableModel model = new UpdatableTableModel();
JTable table = new JTable();
table.setModel(model);
table.getColumn("Status").setCellRenderer(new ProgressCellRender());
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
FileFinderWorker worker = new FileFinderWorker(model);
worker.execute();
}
});
}
public class ProgressCellRender extends JProgressBar implements TableCellRenderer
{
#Override
public Component getTableCellRendererComponent(JTable
table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
int progress = 0;
if (value instanceof Float)
{
progress = Math.round(((Float) value) * 100f);
} else if (value instanceof Integer)
{
progress = (int) value;
}
setValue(progress);
return this;
}
}
public class RowData
{
private File file;
private String type;
private long length;
private float status;
public RowData(File file, String type)
{
this.file = file;
this.type = type;
this.length = file.length();
this.status = 0f;
}
public File getFile()
{
return file;
}
public long getLength()
{
return length;
}
public float getStatus()
{
return status;
}
public String getType()
{
return type;
}
public void setStatus(float status)
{
this.status = status;
}
}
public class UpdatableTableModel extends AbstractTableModel
{
private List<RowData> rows;
private Map<File, RowData> mapLookup;
public UpdatableTableModel()
{
rows = new ArrayList<>(25);
mapLookup = new HashMap<>(25);
}
#Override
public int getRowCount()
{
return rows.size();
}
#Override
public int getColumnCount()
{
return 4;
}
#Override
public String getColumnName(int column)
{
String name = "??";
switch (column) {
case 0:
name = "File";
break;
case 1:
name = "File Type";
break;
case 2:
name = "Size";
break;
case 3:
name = "Status";
break;
}
return name;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex)
{
RowData rowData = rows.get(rowIndex);
Object value = null;
switch (columnIndex)
{
case 0:
value = rowData.getFile();
break;
case 1:
value = rowData.getType();
break;
case 2:
value = rowData.getLength();
break;
case 3:
value = rowData.getStatus();
break;
}
return value;
}
#Override//new value //row to change //column to change
public void setValueAt(Object aValue, int rowIndex, int columnIndex)
{
RowData rowData = rows.get(rowIndex);
switch (columnIndex)
{
case 3:
if (aValue instanceof Float)
{
rowData.setStatus((float) aValue);
}
break;
}
}
public void addFile(File file)
{
RowData rowData = new RowData(file, "A File");
mapLookup.put(file, rowData);
rows.add(rowData);
fireTableRowsInserted(rows.size() - 1, rows.size() - 1);
}
protected void updateStatus(File file, int progress)
{
RowData rowData = mapLookup.get(file);
if (rowData != null) {
int row = rows.indexOf(rowData);
float p = (float) progress / 100f;
setValueAt(p, row, 3);
fireTableCellUpdated(row, 3);
}
}
}
public class FileFinderWorker extends SwingWorker<List<File>, File>
{
private UpdatableTableModel model;
public FileFinderWorker(UpdatableTableModel model)
{
this.model = model;
}
#Override
protected void process(List<File> chunks) //data chunks
{
for (File file : chunks)
{
model.addFile(file);
}
}
#Override
protected List<File> doInBackground() throws Exception
{
String usrHome = "user.home"; // takes the entire home dir
// user.dir will use working directory
// (wherever you save your Java shit)
File files[] = new
File(System.getProperty(usrHome)).listFiles();//grabbing all files from directory.
List<File> lstFiles = new ArrayList<>(Arrays.asList(files));
for (File file : lstFiles)
{
publish(file);
}
return lstFiles;
}
#Override
protected void done()
{
try {
List<File> files = get();
for (File file : files)
{
new FileReaderWorker(model, file).execute();
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
public class FileReaderWorker extends SwingWorker<File, File>
{
private File currentFile;
private UpdatableTableModel model;
public FileReaderWorker(UpdatableTableModel model, File file)
{
this.currentFile = file;
this.model = model;
addPropertyChangeListener(new PropertyChangeListener()
{
#Override
public void propertyChange(PropertyChangeEvent evt)
{
if (evt.getPropertyName().equals("progress"))
{
FileReaderWorker.this.model.updateStatus(currentFile, (int) evt.getNewValue());
}
}
});
}
#Override
protected File doInBackground() throws Exception
{
if (currentFile.isFile())
{
setProgress(0);
long fileLength = currentFile.length();
BufferedReader reader = null;
char[] cbuf = new char[1024];//change this if everything loads too fast
try {
reader = new BufferedReader(new FileReader(currentFile));
int bytesRead = -1;
int totalBytesRead = 0;
while ((bytesRead = reader.read(cbuf)) != -1) {
totalBytesRead += bytesRead;
int progress = (int) Math.round(((double) totalBytesRead / (double) fileLength) *
100d);
setProgress(progress);
Thread.sleep(25);
}
setProgress(100);
} catch (Exception e) {
e.printStackTrace();
setProgress(100);
} finally {
try {
reader.close();
} catch (Exception e) {
}
}
} else {
setProgress(100);
}
return currentFile;
}
}
}
progress bar needs to get into application
You should look into AOP aspectJ.
Using this you could do the task
I need to show suggestions (autocomplete) as the user types in a JTextArea, kind of like cell phone T9.
I don't know how to do this in myTextAreaKeyTyped() event.
This app is a typing helper. It shows variants of characters non-present on the keyboard.
E.G. You press 'A', it shows Â:1, Á:2 ,À:3… 'A' will be replaced if you press 1,2 or 3.
It's already done, but the variants are shown in a JLabel at the bottom of my JFrame, because I don't know how to do this.
Can you please help me out? Thanks in advance.
Here is a snippet to get yourself inspired. You will probably need to reorganize a bit the code to make it more maintainable, but it should give you the gist.
Basically, we listen for key events (I don't find it relevant to listen to document events, for example if the user pastes some text, I don't want the suggestion panel to appear), and when the caret has at least 2 characters behind, we make some suggestions, using a popupmenu containing a JList of suggestions (here suggestions are really not meaningful, but it would not be too hard to bind this to a dictionnary). As for the shortcuts you are mentionning, it should not be too hard to do so.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.BadLocationException;
public class Test {
public class SuggestionPanel {
private JList list;
private JPopupMenu popupMenu;
private String subWord;
private final int insertionPosition;
public SuggestionPanel(JTextArea textarea, int position, String subWord, Point location) {
this.insertionPosition = position;
this.subWord = subWord;
popupMenu = new JPopupMenu();
popupMenu.removeAll();
popupMenu.setOpaque(false);
popupMenu.setBorder(null);
popupMenu.add(list = createSuggestionList(position, subWord), BorderLayout.CENTER);
popupMenu.show(textarea, location.x, textarea.getBaseline(0, 0) + location.y);
}
public void hide() {
popupMenu.setVisible(false);
if (suggestion == this) {
suggestion = null;
}
}
private JList createSuggestionList(final int position, final String subWord) {
Object[] data = new Object[10];
for (int i = 0; i < data.length; i++) {
data[i] = subWord + i;
}
JList list = new JList(data);
list.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setSelectedIndex(0);
list.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
insertSelection();
}
}
});
return list;
}
public boolean insertSelection() {
if (list.getSelectedValue() != null) {
try {
final String selectedSuggestion = ((String) list.getSelectedValue()).substring(subWord.length());
textarea.getDocument().insertString(insertionPosition, selectedSuggestion, null);
return true;
} catch (BadLocationException e1) {
e1.printStackTrace();
}
hideSuggestion();
}
return false;
}
public void moveUp() {
int index = Math.min(list.getSelectedIndex() - 1, 0);
selectIndex(index);
}
public void moveDown() {
int index = Math.min(list.getSelectedIndex() + 1, list.getModel().getSize() - 1);
selectIndex(index);
}
private void selectIndex(int index) {
final int position = textarea.getCaretPosition();
list.setSelectedIndex(index);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
textarea.setCaretPosition(position);
};
});
}
}
private SuggestionPanel suggestion;
private JTextArea textarea;
protected void showSuggestionLater() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
showSuggestion();
}
});
}
protected void showSuggestion() {
hideSuggestion();
final int position = textarea.getCaretPosition();
Point location;
try {
location = textarea.modelToView(position).getLocation();
} catch (BadLocationException e2) {
e2.printStackTrace();
return;
}
String text = textarea.getText();
int start = Math.max(0, position - 1);
while (start > 0) {
if (!Character.isWhitespace(text.charAt(start))) {
start--;
} else {
start++;
break;
}
}
if (start > position) {
return;
}
final String subWord = text.substring(start, position);
if (subWord.length() < 2) {
return;
}
suggestion = new SuggestionPanel(textarea, position, subWord, location);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
textarea.requestFocusInWindow();
}
});
}
private void hideSuggestion() {
if (suggestion != null) {
suggestion.hide();
}
}
protected void initUI() {
final JFrame frame = new JFrame();
frame.setTitle("Test frame on two screens");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
textarea = new JTextArea(24, 80);
textarea.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
textarea.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_ENTER) {
if (suggestion != null) {
if (suggestion.insertSelection()) {
e.consume();
final int position = textarea.getCaretPosition();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
textarea.getDocument().remove(position - 1, 1);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
});
}
}
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN && suggestion != null) {
suggestion.moveDown();
} else if (e.getKeyCode() == KeyEvent.VK_UP && suggestion != null) {
suggestion.moveUp();
} else if (Character.isLetterOrDigit(e.getKeyChar())) {
showSuggestionLater();
} else if (Character.isWhitespace(e.getKeyChar())) {
hideSuggestion();
}
}
#Override
public void keyPressed(KeyEvent e) {
}
});
panel.add(textarea, BorderLayout.CENTER);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test().initUI();
}
});
}
}