import javax.swing.JFrame;
import javax.swing.JTextField;
import com.sun.awt.AWTUtilities;
#SuppressWarnings("serial")
public class TranslucentIssueTest extends JFrame
{
public static void main(String[] args)
{
(new TranslucentIssueTest()).setVisible(true);
}
public TranslucentIssueTest()
{
super();
setUndecorated(true);
setLayout(null);
setSize(300, 300);
AWTUtilities.setWindowOpaque(this, false);
JTextField box = new JTextField();
box.setBounds(30, 150, 100, 25);
add(box);
}
}
The code above creates a textfield on transparent frame.
But when I typed some Chinese characters into the box using an input method, transparent effect was removed automatically. Is there anything wrong with my code?
Thanks in advance.
I ran into what appears to be the same issue and thought I'd post my solution for anyone who finds this question while searching. The problem seems to be due to a bug in the DirectDraw pipeline in Swing. I'm using an older version of Java 7 (update 5), so it's possible that this has been fixed in one of the later releases.
The problem doesn't seem to be with the IME specifically, but rather with the rendering calls that get made by the text field while the IME is active.
The simplest way to work around the problem is to just disable DirectDraw rendering by making the following call before any GUI code is run:
System.setProperty("sun.java2d.noddraw", "true");
If you'd rather not disable DirectDraw rendering entirely, you can work around the specific JTextField issue by overriding its paintComponent method to write to a buffer as in the example below.
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class Test {
public static class JTextField2 extends JTextField {
private static final long serialVersionUID = 1L;
private BufferedImage buffer = null;
#Override public void paintComponent(Graphics g) {
Component window = this.getTopLevelAncestor();
if (window instanceof Window && !((Window)window).isOpaque()) {
// This is a translucent window, so we need to draw to a buffer
// first to work around a bug in the DirectDraw rendering in Swing.
int w = this.getWidth();
int h = this.getHeight();
if (buffer == null || buffer.getWidth() != w || buffer.getHeight() != h) {
// Create a new buffer based on the current size.
GraphicsConfiguration gc = this.getGraphicsConfiguration();
buffer = gc.createCompatibleImage(w, h, BufferedImage.TRANSLUCENT);
}
// Use the super class's paintComponent implementation to draw to
// the buffer, then write that buffer to the original Graphics object.
Graphics bufferGraphics = buffer.createGraphics();
try {
super.paintComponent(bufferGraphics);
} finally {
bufferGraphics.dispose();
}
g.drawImage(buffer, 0, 0, w, h, 0, 0, w, h, null);
} else {
// This is not a translucent window, so we can call the super class
// implementation directly.
super.paintComponent(g);
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
final JFrame frame = new JFrame();
frame.setUndecorated(true);
frame.setBackground(new Color(96, 128, 160, 192));
JTextField textField = new JTextField2();
JButton exitButton = new JButton("Exit");
exitButton.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
frame.dispose();
}
});
frame.add(exitButton, BorderLayout.PAGE_START);
frame.add(textField, BorderLayout.PAGE_END);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Related
Here is my code:
package trialruns;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class TransparentFrame extends JFrame
{
JButton b1;
public TransparentFrame()
{
setTitle("Transparent Frame Demo");
setSize(400,400);
setLayout(new GridBagLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setUndecorated(true);
setVisible(true);
setResizable(true);
setOpacity(0.4f);
}
public static void main(String args[])
{
new TransparentFrame();
}
}
The problem is if I setOpacity<1.0 i get an error :
The frame is decorated at java.awt.Frame.setOpacity(Frame.java:960)
And if I make do setUndecorated(true) then I cant resize the Jframe
I need to be able to resize a transparent JFrame
I also need to be able to access the folders under the transparent frame
I mean if the transparent window is sitting on the desktop and I want to open a particular folder placed under the window then I should be able to do so without the jframe getting minimized.
Is there any way to do this??
I searched online but couldn't find a suitable solution.
Resizing of the frame is handled by the frame itself. When you remove the Border decorations you lose the resizing functionality.
So, you need to manage the resizing of the frame yourself. Check out Component Resizer for a class that will allow you to resize any component.
The change to your code would be:
//setResizable(true); // not needed as this is the default anyway
setOpacity(0.4f);
new ComponentResizer( this );
But is it possible to keep the border opaque
Yes, but you will only get the Swing decorated Border, not the platform Border and decorations:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class TransparentFrame2 extends JFrame
{
public TransparentFrame2()
{
setTitle("Transparent Frame Demo");
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
setBackground( new Color(0, 0, 0, 0) );
setSize(400,400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String args[])
{
new TransparentFrame2();
}
}
Also it is still not possible to access the content behind the frame
Yes, but you need full transparency. If you don't use full transparency then the mouse event is passed to the frame, not the component underneath the frame.
If you what semi transparency then theoretically you could add a MouseListener to the frame to intercept the MouseEvent. Then you can make your frame invisible. Then you could use a Robot to generate a new MouseEvent which will now be dispatched to the screen. You would next to use the frames locationOnScreen(...) method to convert the mouse point from the frames coordinates. I have never tried this approach.
try this.. working for me..
import java.awt.*;
import static java.awt.GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT;
import javax.swing.*;
class TransparentFrame extends JFrame {
JButton b1;
public TransparentFrame() {
setTitle("Transparent Frame Demo");
setSize(400, 400);
setAlwaysOnTop(true);
setLayout(new GridBagLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
setResizable(true);
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
if (g instanceof Graphics2D) {
final int R = 255;
final int G = 255;
final int B = 255;
Paint p =
new GradientPaint(0.0f, 0.0f, new Color(R, G, B, 0),
0.0f, getHeight(), new Color(R, G, B, 0), true);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
};
setContentPane(panel);
JButton button = new JButton("Button");
setBackground(new Color(0,0,0,0));
panel.add(button);
}
public static void main(String args[]) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
boolean isPerPixelTranslucencySupported = gd.isWindowTranslucencySupported(PERPIXEL_TRANSLUCENT);
//If translucent windows aren't supported, exit.
if (!isPerPixelTranslucencySupported) {
System.err.println("PerPixel Translucency is not supported");
System.exit(0);
}
JFrame.setDefaultLookAndFeelDecorated(true);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TransparentFrame tw = new TransparentFrame();
tw.setVisible(true);
}
});
}
}
referenced from this
I have two separate class and driver files, and in the class file I create the paint method:
public void paint(Graphics g){
g.drawLine(......
....
//along with all of my other draw commands
}
Further down in the code, I create a JButton and within this button's action listener I don't know how to use a Graphics object to create more graphics in the JFrame. Should I be adding something to my driver to make this happen, or is there a way to use these graphics within my action listener? Thank you, and any help is appreciated.
You need to draw everything within the paint method. The actionPerformed should only change the state of something already in the paint method, and then call repaint. For example
boolean drawHello = true;
boolean drawWorld = false;
protected void paintComponent(Graphics g) {
super.paintCompoent(g);
if (drawHello)
g.drawString("Hello", 50, 50);
if (drawWorld)
g.drawString("World", 10, 10);
}
Then in your actionPerformed, you can change the state of drawWorld to true and call repaint().
public void actionPerformed(ActionEvent e) {
drawWorld = true;
repaint();
}
So as you can see, everything should be drawn in the paintComponent method. You can just hide and paint renderings, and make them "visible" from a action command. You should already have predefined what could posibly be drawn. Then just change the state of it rendering
And as #MadPrgrammer pointed out, you should not be painting on top-level containers like JFrame. Instead paint on a custom JPanel or JComponent and override the paintComponent method, instead of JFrame and paint
Here's an example where I draw a new square every time the button is pressed. If look at the code, you will see that in the paintComponent method, I loop through a list of Squares and draw them, and in the actionPerformed all I do is add a new Square to the List and call repaint()
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class AddSquares {
private int R = 0;
private int G = 0;
private int B = 0;
private int xLoc = 0;
private int yLoc = 0;
List<Square> squares = new ArrayList<>();
private JButton addSquare = new JButton("Add Square");
private RectsPanel panel = new RectsPanel();
public AddSquares() {
addSquare.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
Color color = new Color(R, G, B);
squares.add(new Square(xLoc, yLoc, color));
panel.repaint();
R += 10;
G += 20;
B += 30;
xLoc += 20;
yLoc += 20;
}
});
JFrame frame = new JFrame("Draw Squares");
frame.add(panel, BorderLayout.CENTER);
frame.add(addSquare, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private class RectsPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Square square : squares) {
square.drawSquare(g);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(250, 250);
}
}
private class Square {
int x = 0;
int y = 0;
Color color;
public Square(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public void drawSquare(Graphics g) {
g.setColor(color);
g.fillRect(x, y, 75 ,75);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
AddSquares addSquares = new AddSquares();
}
});
}
}
It's difficult to be 100%, but it would seem as you don't understand how custom painting is performed in Swing.
Start by taking a look at Performing Custom Painting and Painting in AWT and Swing.
Essentially, painting is arranged by the Repaint Manager, which decides what and when something should be painted. It then calls (through a chain of methods) the paint method of the components it thinks need to be updated, passing it a reference to a Graphics context that should be used to actually paint on.
Basically, when ever your paint method is called, you should create paint the current state of your painting.
You should avoid overriding paint and instead use paintComponent from classes the extend JComponent
Your question is a little on the vague side as to what you are actually wondering about but generally speaking:
We don't override paint in Swing, we override paintComponent.
If you are already aware of this, you may be overriding paint because you are doing it on a JFrame and you found that JFrame does not have a paintComponent method. You shouldn't override paint on a JFrame. Instead, create a JPanel or something to put inside the frame and override paintComponent on the panel.
Question about the ActionListener.
It sounds like you are wanting to do painting outside of paintComponent in which case probably the best way is to do painting to a separate Image. Then you paint the Image on to the panel in paintComponent. You can also put an Image in a JLabel as an ImageIcon. Here is a very simple drawing program using MouseListener that demonstrates this (taken from here):
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
class PaintAnyTime {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new PaintAnyTime();
}
});
}
final BufferedImage image = (
new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB)
);
final JFrame frame = new JFrame();
final JLabel label = new JLabel(new ImageIcon(image));
final MouseAdapter drawer = new MouseAdapter() {
Graphics2D g2D;
#Override
public void mousePressed(MouseEvent me) {
g2D = image.createGraphics();
g2D.setColor(Color.BLACK);
}
#Override
public void mouseDragged(MouseEvent me) {
g2D.fillRect(me.getX(), me.getY(), 3, 3);
label.repaint();
}
#Override
public void mouseReleased(MouseEvent me) {
g2D.dispose();
g2D = null;
}
};
PaintAnyTime() {
label.setPreferredSize(
new Dimension(image.getWidth(), image.getHeight())
);
label.addMouseListener(drawer);
label.addMouseMotionListener(drawer);
frame.add(label);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
#MadProgrammer has already linked to the articles that I was going to link to.
I have just started working with Swing and am trying to draw a button with a custom shape, a triangle in this example. I called the JButton subclass 'ShiftingButton' in the following code because of its unusual behavior. When the mouse enters its region, it is repainted with an offset from its original position. Furthermore the shifted, offset version is drawn in addition to the original position so that both the original and shifted versions appear together. That is, when I run this code, the button is shown as a triangle along the left edge of the window. Then when I run the mouse over the button, a new triangle is drawn (in addition to the old one), shifted down and to the right by about 10 pixels. Resizing the window changes the offset of the phantom button from the original.
Experimenting with mouse clicks shows that only the original, correctly-positioned button is active. The region of the offset phantom button is not active.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Polygon;
public class ShiftingButton extends JButton implements ActionListener {
private Polygon shape;
public ShiftingButton () {
initialize();
addActionListener(this);
}
protected void initialize() {
shape = new Polygon();
setSize(120, 120);
shape.addPoint(0, 0);
shape.addPoint(0, 60);
shape.addPoint(90, 0);
setMinimumSize(getSize());
setMaximumSize(getSize());
setPreferredSize(getSize());
}
// Hit detection
public boolean contains(int x, int y) {
return shape.contains(x, y);
}
#Override
public void paintComponent (Graphics g) {
System.err.println("paintComponent()");
g.fillPolygon(shape);
}
protected void paintBorder(Graphics g) {
}
#Override
public void actionPerformed (ActionEvent ev) {
System.out.println("ShiftingButton ActionEvent!");
}
public static void main (String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
ShiftingButton button = new ShiftingButton();
panel.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
You failed to call super.paintComponent(g) inside the overridden paintComponent(...) method. Moreover, while overriding a method of the Base class, always try to keep the access specifier of the methods, the same, as much as possible. In this case it's protected and not public :-) Now function should be like this :
#Override
protected void paintComponent (Graphics g) {
System.err.println("paintComponent()");
super.paintComponent(g);
g.fillPolygon(shape);
}
EDIT 1 :
Moreover, since you are using a custom shape to be drawn, hence you again failed to specify the ContentAreaFilled property for this JButton in question, hence inside your constructor, you should write setContentAreaFilled(false), for it to work nicely. Though if this doesn't works (for reasons specified in the Docs), then you have to use the plain old Opaque property and set it to false for this JButton using setOpaque(false) :-)
Here is your code with modified changes :
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Polygon;
public class ShiftingButton extends JButton implements ActionListener {
private Polygon shape;
public ShiftingButton () {
setContentAreaFilled(false);
initialize();
addActionListener(this);
}
protected void initialize() {
shape = new Polygon();
setSize(120, 120);
shape.addPoint(0, 0);
shape.addPoint(0, 60);
shape.addPoint(90, 0);
}
#Override
public Dimension getPreferredSize() {
return (new Dimension(120, 120));
}
// Hit detection
public boolean contains(int x, int y) {
return shape.contains(x, y);
}
#Override
protected void paintComponent(Graphics g) {
System.err.println("paintComponent()");
super.paintComponent(g);
g.fillPolygon(shape);
}
protected void paintBorder(Graphics g) {
}
#Override
public void actionPerformed (ActionEvent ev) {
System.out.println("ShiftingButton ActionEvent!");
}
public static void main (String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
ShiftingButton button = new ShiftingButton();
panel.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
I have an image that is to be drawn on a JFrame. The dimensions of the image are dependent on the dimensions of the JFrame.
The JFrame is drawn significantly more often then the JFrame is actually re-sized. Thus I had the image re-sized then stored in the component re-size event and only drew the re-sized image in the draw method.
//called on componentResized
private void scaleImage(){
if((this.getHeight() * this.getWidth()) != 0)
scalledBackGroundImage = backGroundImage.getScaledInstance(this.getWidth(), this.getHeight(), Image.SCALE_FAST);
else
scalledBackGroundImage = null;
}
#Override
public void paint(Graphics g){
if(scalledBackGroundImage != null)
g.drawImage(scalledBackGroundImage, 0, 0, this);
super.paint(g);
}
However I would seem that the re-size event is called after paint when a component is redrawn. Thus the image displayed is the image for the previous frame size. This really becomes a problem with actions like maximize or minimize.
I am looking for a way to detect a JFrame re-size before paint is called.
(I know I could call repaint() on re-size but it seem a bit rude to ask for the component to be drawn twice when re-sizing)
Thanks for any help.
See The Perils of Image.getScaledInstance(). It really is not a very good choice.
Not only do you have the problem you described above, but I get a lot of flickering:
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import javax.swing.text.*;
import java.io.*;
public class ResizeSSCCE extends JPanel
{
Image original;
Image scaled;
public ResizeSSCCE()
{
original = new ImageIcon( "mong.jpg" ).getImage();
scaled = original;
scaleImage();
ComponentListener cl = new ComponentAdapter()
{
#Override
public void componentResized(ComponentEvent e)
{
scaleImage();
}
};
addComponentListener(cl);
}
#Override
public void paintComponent(Graphics g)
{
if (scaled != null)
g.drawImage(scaled, 0, 0, this);
// g.drawImage(original, 0, 0, getWidth(), getHeight(), this);
}
private void scaleImage()
{
if (getHeight() * getWidth() != 0)
scaled = original.getScaledInstance(getWidth(), getHeight(), Image.SCALE_FAST);
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("ResizeSSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new ResizeSSCCE() );
frame.setSize(200, 200);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
Change the code to use your image and then run using the scaled version to see the flickering. Then change the code to use the original image that is scale of the fly to see the difference. As the article suggests scaling on the fly is the better approach.
Add a component listener to JFrame as
jFrame.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
//Your resize method here
}
});
this is my first post here and I have a question that seems really nooby, but this has been troubling me for the past hour or so.
I'm making a simple JFrame with a JPanel in it, but the Windows 7 border frame appears to be blocking my view of parts of the panel. For instance, if I draw a little square at coordinate 0,0, it will not appear and I suspect it's behind the window frame.
I've tried messing around with pack, setsize, setpreferred size, setresizable, and different layouts, but I can't get it to show the top 20 pixels or so!
This is what I have:
public RedSunGame() {
super("Red Sun");
rs = new JPanel(new BorderLayout(), true);
rs.setPreferredSize(new Dimension(WIDTH, HEIGHT));
add(rs, "Center");
setPreferredSize(new Dimension(WIDTH, HEIGHT));
pack();
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
EDIT:
Thanks for all of your replies, sorry for the lack of info :)
I'm using a double buffer strategy I saw in a book. gameRender and paintScreen are in a standard game loop. My RedSunGame class extends JFrame. All the relevant code you could ask for in addition to above:
private static final int WIDTH = 500;
private static final int HEIGHT = 500;
private JPanel rs;
private Graphics2D g2d;
private Image dbImage;
private void gameRender() {
//create buffer
if (dbImage == null){
dbImage = createImage(WIDTH, HEIGHT);
g2d = (Graphics2D)dbImage.getGraphics();
}
//clear screen
g2d.setColor(Color.white);
g2d.fillRect(0, 0, WIDTH, HEIGHT);
g2d.setColor(Color.blue);
g2d.setFont(font);
g2d.drawString("FPS: " + FPS, 0, HEIGHT);
g2d.fillRect(30, 30, 10, 10);
}
private void paintScreen() {
Graphics g;
try {
g = getGraphics();
if ((g != null) && (dbImage != null))
g.drawImage(dbImage, 0, 0, null);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
catch (Exception e)
{ System.out.println("Graphics context error: " + e); }
}
With my current settings it looks like this.
http://i.imgur.com/qaabC.png
This is what happens if I have g2d.fillRect(30, 30, 10, 10), the only change being the coordinates 30,30 instead of 0,0. It's definitely hiding behind the border up top.
http://i.imgur.com/uzfFe.png
Also, setting it to BorderLayout.CENTER doesn't seem to make a difference in any of these cases.
(sorry it won't let new users post images)
EDIT:
I figured it out. I was drawing directly to the JFrame. #Guillaume Polet I see why you shouldn't override the paint method of JFrames as it draws to the frame and not the panel that should actually display content!! Thanks
Here is a sample code that shows how your goal can be achieved. Try to spot the differences with your code to find what is wrong:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class RedSunGame {
private static final int SQUARE_SIZE = 20;
private JPanel rs;
private JFrame frame;
private void initUI() {
frame = new JFrame("Red Sun");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
rs = new JPanel(new BorderLayout()) {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.YELLOW);
g.fillRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
}
#Override
public Dimension getPreferredSize() {
Dimension preferredSize = super.getPreferredSize();
// Let's make sure that we have at least our little square size.
preferredSize.width = Math.max(preferredSize.width, SQUARE_SIZE);
preferredSize.height = Math.max(preferredSize.height, SQUARE_SIZE);
return preferredSize;
}
};
frame.add(rs);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
RedSunGame redSunGame = new RedSunGame();
redSunGame.initUI();
}
});
}
}
Verify that WIDTH and HEIGHT are > 0.
Try this:
//add(rs, "center");
add(rs, BorderLayout.CENTER);
you may got your answer but for a newbie to java swing i suggest that you should the Net-beans IDE. it graphically adds and lays out the GUI and you dont need to write any hand-written code. It's a great place to start, as stated here:
http://docs.oracle.com/javase/tutorial/uiswing/learn/index.html