Java JScrollBar not scrolling all the way - java

So I have asked a previous question and this is a follow up to it, and I think it deserves its own question. I have this code where a JPanel of a certain size exists in a JScrollPane. The thing is, I want to set my own maximum values to the scroll bars of the JScrollPane which is easy using the bar.setMaximum(value) method. However, there is a weird problem occurring when I scroll the bars without using my mouse itself but rather with the W, A, S, D keys.
The problem is that I set the scroll bars to new maximums, and make a change listener to update the maximums of the scroll bars (because if you looked at my previous question, the scroll bars values were returning to their default max sizes and not the ones I set them to). I thought I solved the problem to the previous question, but now the scroll bars won't scroll all the way, and stop at a certain point. Any ways to fix this?
Note: I don't want to change the JPanel's size that exists in the scroll pane, I just want making the scrolling longer when going from side to side with the W, A, S, D keys. (My unit increment is 1 which is too large for me, so changing the max size of the scroll bars seemed fit as that would decrease an increment’s size overall)
Here is the minimal reproducible (I drew a rectangle in the JPanel map to help see what's going on):
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
import java.awt.*;
public class Test implements KeyListener, ChangeListener {
private static JScrollPane view;
public Test() {
create();
}
public static void main(String[] args) {
new Test();
}
public void create() {
JFrame frame = new JFrame(); //make frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1000, 1000);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
SpringLayout layout = new SpringLayout();
JPanel base = new JPanel();
base.setPreferredSize(new Dimension(1000, 1000));
base.setLayout(layout);
JPanel map = new JPanel() {
public void paint(Graphics g) {
super.paint(g);
g.drawRect(0, 0, 995, 100);
}
};
map.setPreferredSize(new Dimension(1000, 1000));
view = new JScrollPane(map);
view.setFocusable(true);
view.addKeyListener(this);
view.setPreferredSize(new Dimension(300, 300));
layout.putConstraint(SpringLayout.HORIZONTAL_CENTER, view, 0, SpringLayout.HORIZONTAL_CENTER, base);
layout.putConstraint(SpringLayout.VERTICAL_CENTER, view, 0, SpringLayout.VERTICAL_CENTER, base);
base.add(view); //add scrollpane to base jpanel
frame.add(base);
frame.setVisible(true);
JScrollBar hBar = view.getHorizontalScrollBar();
JScrollBar vBar = view.getVerticalScrollBar();
hBar.getModel().addChangeListener(this);
vBar.getModel().addChangeListener(this);
hBar.getModel().setMaximum(10*800);
vBar.getModel().setMaximum(10*800);
}
public void stateChanged(ChangeEvent event) { //change max whenever model's max tries to default
BoundedRangeModel model = (BoundedRangeModel) event.getSource();
model.setMaximum(10*800);
}
public void keyPressed(KeyEvent event) { //W, A, S, D keys to change values of jscrollbars
int verticalValue = view.getVerticalScrollBar().getModel().getValue();
int horizontalValue = view.getHorizontalScrollBar().getModel().getValue();
switch (event.getKeyCode()) {
case KeyEvent.VK_W:
view.getVerticalScrollBar().getModel().setValue(verticalValue - 10);
break;
case KeyEvent.VK_S:
view.getVerticalScrollBar().getModel().setValue(verticalValue + 10);
break;
case KeyEvent.VK_A:
view.getHorizontalScrollBar().getModel().setValue(horizontalValue - 10);
break;
case KeyEvent.VK_D:
view.getHorizontalScrollBar().getModel().setValue(horizontalValue + 10);
break;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}

Related

Why doesn't the image paint over my JPanel?

I have been struggling with this for some time. At first, I only used ActionListener, then I added the paintComponent, but I have no idea what to put there. I read some tutorials and used their code as an example, but it still doesn't work. Right now, the end result is the same as it was without PaintComponent.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Scream extends JPanel {
private JButton button = new JButton("OK");
private Color screenColor;
private JPanel panel = new JPanel();
private JFrame frame;
private Dimension screenSize;
private ImageIcon image;
private JLabel label = new JLabel(image);
private int x;
private int y;
private boolean mouseClicked;
public Scream() {
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e ) {
if (e.getSource() == button) {
mouseClicked = true;
frame.getContentPane().add(label);
frame.setSize(image.getIconWidth(), image.getIconHeight());
panel.repaint();
}
}
});
frame = new JFrame ("Existential angst");
screenColor = new Color(150, 100, 0);
panel.setBackground( screenColor );
frame.add(button, BorderLayout.PAGE_END);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1300, 700);
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
image.paintComponent(this, g, 1300, 700);
}
public static void main (String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Scream scream = new Scream();
}
});
}
}
If you are trying to dynamically add an image to a panel then you need to add the label to the panel. There is no need for any custom painting.
The basic code for adding components to a visible GUI is:
panel.add(...);
panel.revalidate();
panel.repaint();
Also, don't attempt to set the size of the frame to the size of the image. A frame contains a titlebar and borders. Instead you can use frame.pack();
I noticed a couple of issues:
image is never initialized to anything so it is null, effectively making the label empty. I assume maybe your example was just incomplete?
Once I initialized the image to something, your example still did not work. Turns out adding label without specifying any constraint basically does nothing (I assume since adding a component to a border layout without a constraint puts it in the center where panel already is). When I added the label to BorderLayout.NORTH, everything worked (though resizing the frame to the size of the image makes it only partially visible since the frame includes the OK button)

Why i need to click twice to let my JButton work?

I'm building a program that draws random (User input) rectangles on a JPanel.
Problem 1:
Whenever I type a number in my JTextfield,I need to click twice on
the JBUtton for Rectangles to show up.
Problem 2:
When i type a new number in the JTextField the number of that don't
show the rectangle but it shows the rectangles I typed in previous.
CODE:
private void init() {
final int FRAME_WIDHT = 800;
final int FRAME_HEIGHT = 1000;
int input = 3;
JFrame frame = new JFrame();
frame.setSize(FRAME_WIDHT, FRAME_HEIGHT);
frame.setTitle("Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
west = new JPanel();
west.setSize(500, 500);
west.setBorder(BorderFactory.createLineBorder(Color.black));
east = new JPanel();
east.setSize(300, 1000);
button = new JButton("Add squares");
field = new JTextField(10);
button.setSize(100, 50);
east.add(button);
east.add(field);
east.setBorder(BorderFactory.createLineBorder(Color.black));
button.addActionListener(new java.awt.event.ActionListener() {
#Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
JButton1ActionPerformed(evt);
}
public void JButton1ActionPerformed(ActionEvent evt) {
int aantalRect = Integer.parseInt(field.getText());
MyDrawing draw = new MyDrawing(aantalRect);
west.add(draw);
draw.revalidate();
draw.repaint();
}
});
frame.add(west, BorderLayout.CENTER);
frame.add(east, BorderLayout.EAST);
frame.setResizable(true);
frame.setVisible(true);
}
public static void main(String[] a) {
P1027 form = new P1027();
}
}
class MyDrawing extends JPanel {
int input = 0;
public MyDrawing(int i) {
this.input = i;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Random r = new Random();
setPreferredSize(new Dimension(500, 1000));
for (int i = 0; i < input; i++) {
int x = r.nextInt(460);
int y = r.nextInt(960);
g.drawRect(x, y, 40, 40);
}
}
Can any one tell me how to fix that?
Problem 1: You're not be seeing the squares being drawn on your MyDrawing JPanel the first time because you are calling the setPreferredSize(...) method, when you really should be overriding the getPreferredSize() method as explained by this answer. It is also possible that they are being drawn off-screen. You set the preferred height of MyDrawing to 1000, which doesn't fit on my laptop's screen (The green line is the border of a MyDrawing).
To fix Problem 1, override the method and lower the preferred height if necessary:
class MyDrawing extends JPanel {
... //Constructor
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500); //Changed from 1000 to 500
}
... //paintComponent(...)
//If you change 1000 to 500, don't forget to change 960 to 460 too
}
Problem 2: You're seeing the amount of rectangles you typed into the JTextField previously because:
You are forgetting to remove the previously added MyDrawing from west before adding the new one.
You are calling revalidate() and repaint() on draw when you should be calling it on its parent component, west.
To fix problem 2, remove the old MyDrawing from west, add the new one, then call revalidate() and repaint():
...
public void JButton1ActionPerformed(ActionEvent evt) {
west.removeAll(); //If the old MyDrawing is the only thing
//that has been added to west. Otherwise use
//remove(int index) or remove(Component comp)
west.add(draw);
west.revalidate();
west.repaint();
}
...
Other things:
You switched the T and H around in FRAME_WIDTH.
You could put the code in JButton1ActionPerformed(...) into the actual actionPerformed method.
Your JFrame looks exactly the same with and without the calls to setSize(...) on west, east, and button and that answer I mentioned earlier suggests not using those methods, so consider removing them.

JTabbedPanel change selected tab background color

I'm attempting to change the color of the border of a JTabbedPane based on the selected tab. Using answers here and on the web, I've managed this:
import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
public class TabbedPaneTest implements Runnable {
JTabbedPane pane = new JTabbedPane();;
public void run() {
// magenta border first so any changes will be obvious
setTabbedPaneBorderColor(new Color(255, 0, 255));
JPanel container = new JPanel();
container.setSize(new Dimension(500, 200));
pane.setPreferredSize(new Dimension(400, 200));
pane.addTab("A", createTab(Color.RED));
pane.addTab("B", createTab(Color.YELLOW));
pane.addTab("C", createTab(Color.BLUE));
pane.addChangeListener(new TabSelected());
container.add(pane);
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(container);
frame.setSize(500, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JPanel createTab(Color color) {
JPanel p = new JPanel();
p.setBorder(BorderFactory.createLineBorder(color, 2));
return p;
}
private class TabSelected implements ChangeListener {
#Override
public void stateChanged(ChangeEvent e) {
int index = pane.getSelectedIndex();
switch (index) {
case 0:
setTabbedPaneBorderColor(Color.RED);
break;
case 1:
setTabbedPaneBorderColor(Color.YELLOW);
break;
case 2:
setTabbedPaneBorderColor(Color.BLUE);
break;
}
}
}
public void setTabbedPaneBorderColor(Color tabBorderColor) {
UIManager.put("TabbedPane.borderHightlightColor", tabBorderColor);
UIManager.put("TabbedPane.darkShadow", tabBorderColor);
UIManager.put("TabbedPane.shadow", tabBorderColor);
UIManager.put("TabbedPane.light", tabBorderColor);
UIManager.put("TabbedPane.highlight", tabBorderColor);
UIManager.put("TabbedPane.focus", tabBorderColor);
UIManager.put("TabbedPane.selectHighlight", tabBorderColor);
pane.setUI(new BasicTabbedPaneUI() {
#Override
protected void installDefaults() {
super.installDefaults();
highlight = UIManager.getColor("TabbedPane.light");
lightHighlight = UIManager.getColor("TabbedPane.highlight");
shadow = UIManager.getColor("TabbedPane.shadow");
darkShadow =UIManager.getColor("TabbedPane.darkShadow");
focus = UIManager.getColor("TabbedPane.focus");
}
});
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new TabbedPaneTest());
}
}
In particular, the setTabbedPaneBorderColor() method does exactly what I wanted (that is, it modifies the fancy border around the tabs, rather than the border on the panels contained in it or a plain rectangular border around the entire space the JTabbedPane occupies). For some reason this example throws an error that doesn't show up in my actual program (I think it's related to the SwingWorker and EDT). Now I'm trying to figure out how to change the selected tab's background.
The relevant property is
UIManager.put("TabbedPane.selected",Color.MAGENTA);
However, I don't seem to have a way to use that in the tabUI (it's baffling, but there's no background Color variable in BasicTabbedPaneUI).
Edit: Hopefully someone more knowledgeable will come by with a good answer, but if you googled this my current solution is to use a neutral color for the selected tab's background color since there seems to be no simple way to update it. I also switched to a neutral tab border (even though you CAN update that as the example shows) and created the colored borders inside the contained JPanels. It's not ideal, but it looks pretty good and I don't have time to continue looking for a cleaner solution at the moment.
This is worked for me
UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Enabled].backgroundPainter", new BackgroundPainter(Color.white));
UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Enabled+MouseOver].backgroundPainter", new BackgroundPainter(Color.white));
UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Enabled+Pressed].backgroundPainter", new BackgroundPainter(Color.white));
UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Focused+MouseOver+Selected].backgroundPainter", new BackgroundPainter(Color.white));
UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Focused+Pressed+Selected].backgroundPainter", new BackgroundPainter(Color.white));
UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Focused+Selected].backgroundPainter", new BackgroundPainter(Color.GRAY));
UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[MouseOver+Selected].backgroundPainter", new BackgroundPainter(Color.white));
UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Pressed+Selected].backgroundPainter", new BackgroundPainter(Color.white));
UIManager.getLookAndFeelDefaults().put("TabbedPane:TabbedPaneTab[Selected].backgroundPainter", new BackgroundPainter(Color.white));
BackgroundPainter class
public class BackgroundPainter implements Painter<JComponent> {
private Color color = null;
BackgroundPainter(Color c) {
color = c;
}
#Override
public void paint(Graphics2D g, JComponent object, int width, int height) {
if (color != null) {
g.setColor(color);
g.fillRect(0, 0, width - 1, height - 1);
}
}
}
for me, it worked, I just set the UImanager's TabbedPane.selected color property before creation of JTabbedPane object.
UIManager.put("TabbedPane.selected", Color.red);
tabbedPane = new JTabbedPane();
Refer this link, i'm sure it will work for you too.
http://esus.com/changing-the-color-of-the-selected-tab-of-a-jtabbedpane/

Java Swing Scrolling By Dragging the Mouse

I am trying to create a hand scroller that will scroll as you drag your mouse across a JPanel. So far I cannot get the view to change. Here is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HandScroller extends JFrame {
public static void main(String[] args) {
new HandScroller();
}
public HandScroller() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
final JPanel background = new JPanel();
background.add(new JLabel("Hand"));
background.add(new JLabel("Scroller"));
background.add(new JLabel("Test"));
background.add(new JLabel("Click"));
background.add(new JLabel("To"));
background.add(new JLabel("Scroll"));
final JScrollPane scrollPane = new JScrollPane(background);
MouseAdapter mouseAdapter = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
JViewport viewPort = scrollPane.getViewport();
Point vpp = viewPort.getViewPosition();
vpp.translate(10, 10);
background.scrollRectToVisible(new Rectangle(vpp, viewPort.getSize()));
}
};
scrollPane.getViewport().addMouseListener(mouseAdapter);
scrollPane.getViewport().addMouseMotionListener(mouseAdapter);
setContentPane(scrollPane);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
}
I would think that this would move the view by 10 in the x and y directions, but it is not doing anything at all. Is there something more that I should be doing?
Thanks.
I think so you can move the view in all directions with this code
public void mouseDragged(MouseEvent e) {
JViewport viewPort = scroll.getViewport();
Point vpp = viewPort.getViewPosition();
vpp.translate(mouseStartX-e.getX(), mouseStartY-e.getY());
scrollRectToVisible(new Rectangle(vpp, viewPort.getSize()));
}
public void mousePressed(MouseEvent e) {
mouseStartX = e.getX();
mouseStartY = e.getY();
}
Your code does work. Simply, there is nothing to scroll, as the window is large enough (actually, pack() has caused the JFrame to resize to fit the preferred size and layouts of its subcomponents)
Remove pack(); and replace that line with, say, setSize(60,100); to see the effect.
It is working. However, when you run this code, the JScrollPane is made large enough to fit all your items. Add (for instance)
scrollPane.setPreferredSize(new Dimension(50, 50));
and you'll see that your mouse events work fine.

Thread sleep inside of actionPerformed method

First of all I want to say I'm aware this aproach is wrong so I'm asking this question because of pure curiousity. Lets say I have a swing application like this:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ThreadSleeping {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("Load");
JLabel label = new JLabel();
public ThreadSleeping() {
panel.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
label.setIcon(new ImageIcon(
"C:/Users/Public/Pictures/Sample Pictures/Tulips.jpg"));
System.out.println("Tulips painted");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
label.setIcon(new ImageIcon(
"C:/Users/Public/Pictures/Sample Pictures/Koala.jpg"));
System.out.println("Koala painted");
}
});
frame.add(panel, BorderLayout.NORTH);
frame.add(label, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(1024, 768);
// frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ThreadSleeping();
}
});
}
}
Basically when I click a Load button I expect that Tulips.jpg image displays then GUI freezes for a 2 seconds and after that I expect that Koala.jpg image displays. But what happens is that: I click on button, GUI freezes for a 2 seconds and Koala.jpg displays. No Tulips.jpg before that. But thing that confuses me is when I put those System.out.println("Tulips painted"); and System.out.println("Koala painted");. So when I click on button it prints "Tulips painted" and after 2 seconds "Koala painted". Can someone tell me whats going on here? Regards.
works in this case, because you programatically freeze ouf Swing GUI, but there is/aren't another update(s), ot another JComponent(s)
doens't works in the case that there are a few another updated to the Swing GUI, Thread.sleep(int) freeze Event Dispatch Thread,
by default all updates to the JComponents XxxModels never will be visible on the JComponents view
example until sleep ended you'll lost all updated to the GUI
The point I intended to make in my comment:
if you sleep the edt, the resulting mis-behaviour is basically unpredictable.
Unpredictable in the sense that you can't know what will happen or not. All we can do, is guess ...
The technical reason is that most ui updates don't happen immediately but are scheduled: we can't really know what's waiting in the line behind us. Remember: it's only one lane, and when in the actionPerformed, it's we that are sitting in it.
For educational reasons, the code below is the original code with a couple of lines to un/comment to demonstrate different scenarios.
[0] resetting the icon before/after sleeping: as you already noticed, the first doesn't show even though the property is taken. Technical reason: visual update happens via label.repaint() which is scheduled on the EDT for latter processing (as its api doc states)
[1] skimming the api doc, we notice another method: paintImmediately(...) which is documented to do exactly what it's name says and allowed - as we are on the EDT - is allowed to be called. Looks like success, the yellow icon shows up.
[2] but wait: being in the center of a Borderline, the label fills that area anyway, independent of whether or not it has an icon. Let's try to put it into a region that requires a re-layout, as f.i. into the south. Back to square [0], yellow icon not showing.
[3] looking into the source of setIcon(..) reveals that layout is ... scheduled again. We learned in square [1] that we can force thingies to happen immediately, in case of layout that would be the pair invalidate() / validate(). Bingo, yellow icon even when in south.
[4] nasty subclass which schedules the icon property setting (note: while contrived here there is nothing in its contract that hinders subclasses to do it!). As the property isn't even set, yellow isn't showing, back to square [0]
At the end of the day (but before going to sleep the EDT :-), there is simply no way to reliably predict the visual outcome during the sleep. And visuals are only the tip of the ice...
/**
* Unpredictable behaviour when sleeping the EDT.
* http://stackoverflow.com/q/15600203/203657
*
* [0] run as-is: property set but yellow not showing
* [1] uncomment paintImmediately: yellow showing in center
* [2] add label to south: yellow not showing
* [3] force immediate in-/validation: yellow showing in south
* [4] subclass label with invoked property setting:
* property not set, yellow not showing
*
*/
public class ThreadSleeping {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("Load");
JLabel label = new JLabel() {
// [4] subclass implemented to schedule the property setting
// #Override
// public void setIcon(final Icon icon) {
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
// superSetIcon(icon);
//
// }
// });
// }
//
// protected void superSetIcon(Icon icon) {
// super.setIcon(icon);
// }
//
};
public ThreadSleeping() {
panel.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Icon firstIcon = new FixedIcon(Color.YELLOW, 100, 100);
Icon secondIcon = new FixedIcon(Color.RED, 500, 500);
label.setIcon(firstIcon);
// check if the property is already set
System.out.println(label.getIcon());
// following lines try to force the output before going to sleep
// [3] paintImmediately + force immediate re-layout
// label.invalidate();
// label.getParent().validate();
// {1] paintImmediately (fine for center, no effect for south)
// ((JComponent) label.getParent()).paintImmediately(0, 0, 5000, 5000);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
label.setIcon(secondIcon);
}
});
frame.add(panel, BorderLayout.NORTH);
// un/comment one of the following, placing the
// label either in CENTER (= sized to fill)
frame.add(label, BorderLayout.CENTER);
// [2] or in SOUTH (= sized to pref)
// frame.add(label, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(1024, 768);
frame.setVisible(true);
}
/**
* Simple fixed size Icon filling its area.
*/
public static class FixedIcon implements Icon {
private Color background;
private int width;
private int height;
public FixedIcon(Color background, int width, int height) {
this.background = background;
this.width = width;
this.height = height;
}
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(background);
g.fillRect(0, 0, width, height);
}
#Override
public int getIconWidth() {
return width;
}
#Override
public int getIconHeight() {
return height;
}
#Override
public String toString() {
return "[" + background + " w/h " + width + "/" + height + "]";
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ThreadSleeping();
}
});
}
}

Categories