I am trying to add background image in jTable but when I run code nothing shown. only white color and no jTable shown and my java Application hangs also. is there any thing wrong in this code. here is the preview also.
import javax.swing.table.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class Main extends JFrame
{
public Main() {
JTable table = new JTable(100, 5) {
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
if (c instanceof JComponent) {
((JComponent) c).setOpaque(false);
}
return c;
}
};
ImageJScrollPane isp = new ImageJScrollPane(table);
isp.setBackgroundImage(new ImageIcon("/Images/user/lockscreen.png"));
getContentPane().add(isp);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
public static void main(String [] args) {
Main main = new Main();
main.setSize(400, 400);
main.setVisible(true);
}
}
class ImageJScrollPane extends JScrollPane
{
private ImageIcon image = null;
public ImageJScrollPane() {
this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
public ImageJScrollPane(Component view) {
this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
public ImageJScrollPane(Component view, int vsbPolicy, int hsbPolicy) {
super(view, vsbPolicy, hsbPolicy);
if (view instanceof JComponent) {
((JComponent) view).setOpaque(false);
}
}
public ImageJScrollPane(int vsbPolicy, int hsbPolicy) {
this(null, vsbPolicy, hsbPolicy);
}
public void setBackgroundImage(ImageIcon image) {
this.image = image;
}
public void paint(Graphics g) {
// Do not use cached image for scrolling
getViewport().setBackingStoreEnabled(true);
if (image != null) {
Rectangle rect = getViewport().getViewRect();
for (int x=0; x<rect.width; x+=image.getIconWidth()) {
for (int y=0; y<rect.height; y+=image.getIconHeight()) {
g.drawImage(image.getImage(), x, y, null, null);
}
}
super.paint(g);
}
}
}
Here is one way:
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
setLayout( new BorderLayout() );
JTable table = new JTable(5, 5);
table.setOpaque( false );
DefaultTableCellRenderer renderer =
(DefaultTableCellRenderer)table.getDefaultRenderer(Object.class);
renderer.setOpaque(false);
JScrollPane scrollPane = new JScrollPane( table );
scrollPane.setOpaque( false );
scrollPane.getViewport().setOpaque( false );
final ImageIcon icon = new ImageIcon("mong.jpg");
JPanel background = new JPanel( new BorderLayout() )
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(icon.getImage(), 0, 0, getWidth(), getHeight(), this);
}
};
background.add( scrollPane );
add(background);
}
private static void createAndShowGUI()
{
JPanel panel = new JPanel();
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Make sure the /Images/user/lockscreen.png is in classpath, and also you are using absolute path '/' instead use relative path like ../ or ./ (or) make sure the absolute path is valid.
Related
I need to draw in AWT/Swing rectangles that are moving from frame to frame.
I have a Playground class
public Playground(int sizeX, int sizeY)
{
frame = new JFrame();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setSize(sizeX, sizeY);
panel.setDoubleBuffered(true);
panel.setVisible(true);
frame.add(panel);
frame.pack();
frame.setSize(sizeX, sizeY);
}
public void refresh()
{
panel.repaint();
}
public Graphics getGraphics()
{
return panel.getGraphics();
}
This is the class in which objects should be drawn:
public class Star {
private static int size = 10;
private int posX;
private int posY;
public Star(int posX, int posY)
{
this.posX = posX;
this.posY = posY;
}
public void paint(Graphics g)
{
g.fillRect(posX, posY, size, size);
}
public int getPosX() {
return posX;
}
public int getPosY() {
return posY;
}
}
This is the main method:
public static void main(String[] args) {
Playground playground = new Playground(400, 400);
Star star = new Star(100, 100);
Star star2 = new Star(125, 125);
while(1 == 1)
{
playground.refresh();
star.paint(playground.getGraphics());
star2.paint(playground.getGraphics());
}
}
The objects are drawn but are flickering, how can I stop it from flickering?
Edit: I solved the flickering for one element, by changing the refresh method to:
public void refresh()
{
panel.getGraphics().clearRect(0,0, panel.getWidth(), panel.getHeight());
}
Unfortunately only one Element is not flickering all others are still flickering.
The following is a one-file mcve that demonstrates moving (rotating for simplicity) a rectangle by custom painting.
One-file meaning that you can copy-paste the entire code into one file (AnimateRectangle.java) and execute it.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class AnimateRectangle {
private JFrame frame;
public AnimateRectangle(Model model){
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new MyJPanel(model);
panel.setDoubleBuffered(true);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
void refresh() {
frame.repaint();
}
public static void main(String[] args) throws InterruptedException {
Controller controller = new Controller(400, 400);
while (true) {
Thread.sleep(1000);
SwingUtilities.invokeLater(()->controller.animate());
}
}
}
//"wires" gui and model
class Controller{
private Model model;
private AnimateRectangle view;
Controller(int sizeX, int sizeY){
model = new Model(sizeX, sizeY);
view = new AnimateRectangle(model);
}
void animate() {
int newAngle = (model.getAngle() < 360 ) ? model.getAngle()+1 : 0 ;
model.setAngle(newAngle);
view.refresh();
}
}
//represents the inforamtion the GUI needs
class Model{
int sizeX, sizeY, angle = 0;
public Model(int sizeX, int sizeY) {
this.sizeX = sizeX;
this.sizeY = sizeY;
}
int getSizeX() { return sizeX; }
int getSizeY() {return sizeY;}
int getAngle() {return angle;}
//degrees
void setAngle(int angle) { this.angle = angle; }
}
//a JPanel with custom paint component
class MyJPanel extends JPanel {
private Model model;
public MyJPanel(Model model) {
this.model = model;
setPreferredSize(new Dimension(model.getSizeX(), model.getSizeY()));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.RED);
int sizeX = model.getSizeX(), sizeY = model.getSizeY();
g2d.rotate(Math.toRadians(model.getAngle()), sizeX /2, sizeY/2);
g2d.fillRect(sizeX/4, sizeY/4, sizeX/2, sizeY/2);
}
}
A better option (see camickr comment) is to animate using swing Timer. To do so, remove animate() method, and replace it with :
void animateWithTimer(){
new Timer(1000,new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int newAngle = (model.getAngle() < 360 ) ? model.getAngle()+1 : 0 ;
model.setAngle(newAngle);
view.refresh();
}
}).start();
}
and change main to use it :
public static void main(String[] args) throws InterruptedException {
Controller controller = new Controller(400, 400);
controller.animateWithTimer();
}
So basically if I put JPanels inside a JPanel that uses GridBagLayout and I restrict the size with setPreferredSize, eventually it reaches a point where it can't hold all of them, and it exhibits the behavior shown in the attached picture:
I'm making an accordion. This is just an example to showcase the problem I'm having. Each part of the accordion can open individually and they're of arbitrary size and get added on the fly. Its easy enough to get the heights of all the individual panels and compare them against the total height, but when too many are added it exhibits the crunching behavior I've shown. This also shrinks the heights so its much more difficult to determine when the crunching has happened. I would have to cache heights and somehow pre-calculate the heights of the new parts getting added. The end goal is to remove older panels when a new panel is added and there isn't enough room for it.
Is there an easy way to determine what height something would be if it weren't constrained, or maybe a supported way to detect when such crunching has is happening (so I can quickly thin it out before it gets painted again)? An option that makes GridBagLayout behave like some other layouts and overflow into hammerspace instead of compressing would work too.
Code for example:
import java.awt.*;
import java.awt.event.*;
import javaisms.out;
import javax.swing.*;
public class FoldDrag extends JLayeredPane {
public TexturedPanel backingPanel = new TexturedPanel(new GridBagLayout(),"data/gui/grayerbricks.png");
static JPanel windowbase=new JPanel();
static JPanel restrictedpanel=new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
public FoldDrag() {
JButton addpan = new JButton("Add things");
windowbase.add(addpan);
windowbase.add(restrictedpanel);
restrictedpanel.setBackground(Color.red);
restrictedpanel.setPreferredSize(new Dimension(200,200));
gbc.weighty=1;
gbc.weightx=1;
gbc.gridx=0;
gbc.gridy=0;
gbc.gridheight=1;
gbc.gridwidth=1;
gbc.fill=GridBagConstraints.HORIZONTAL;
addpan.addActionListener(new ActionListener() {
int number=0;
#Override
public void actionPerformed(ActionEvent e)
{
number++;
gbc.gridy=number;
JPanel tmppanel = new JPanel();
tmppanel.setPreferredSize(new Dimension(100,30));
if(number%3==0)
tmppanel.setBackground(Color.blue);
if(number%3==1)
tmppanel.setBackground(Color.yellow);
if(number%3==2)
tmppanel.setBackground(Color.green);
restrictedpanel.add(tmppanel,gbc);
restrictedpanel.validate();
}
});
windowbase.setVisible(true);
}
private static void createAndShowUI() {
JFrame frame = new JFrame("DragLabelOnLayeredPane");
frame.getContentPane().add(windowbase);
FoldDrag thedrag=new FoldDrag();
windowbase.add(thedrag);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(300,300));
frame.pack();
frame.setResizable(true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
out.active=true;
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
EDIT: Seems I didn't describe my version of the accordion very well. Here's a link.
You have particular requirement which may be better served through the use of it's layout manager. This provides you the ability to control every aspect of the layout without the need to resort to hacks or "work arounds" which never quite work or have bizarre side effects
public class AccordionLayout implements LayoutManager {
// This "could" be controlled by constraints, but that would assume
// that more then one component could be expanded at a time
private Component expanded;
public void setExpanded(Component expanded) {
this.expanded = expanded;
}
public Component getExpanded() {
return expanded;
}
#Override
public void addLayoutComponent(String name, Component comp) {
}
#Override
public void removeLayoutComponent(Component comp) {
}
#Override
public Dimension preferredLayoutSize(Container parent) {
Dimension size = minimumLayoutSize(parent);
if (expanded != null) {
size.height -= expanded.getMinimumSize().height;
size.height += expanded.getPreferredSize().height;
}
return size;
}
#Override
public Dimension minimumLayoutSize(Container parent) {
int height = 0;
int width = 0;
for (Component comp : parent.getComponents()) {
width = Math.max(width, comp.getPreferredSize().width);
height += comp.getMinimumSize().height;
}
return new Dimension(width, height);
}
#Override
public void layoutContainer(Container parent) {
Insets insets = parent.getInsets();
int availableHeight = parent.getHeight() - (insets.top + insets.bottom);
int x = insets.left;
int y = insets.top;
int maxSize = 0;
Dimension minSize = minimumLayoutSize(parent);
if (expanded != null) {
minSize.height -= expanded.getMinimumSize().height;
// Try an honour the preferred size the expanded component...
maxSize = Math.max(expanded.getPreferredSize().height, availableHeight - minSize.height);
}
int width = parent.getWidth() - (insets.left + insets.right);
for (Component comp : parent.getComponents()) {
if (expanded != comp) {
comp.setSize(width, comp.getMinimumSize().height);
} else {
comp.setSize(width, maxSize);
}
comp.setLocation(x, y);
y += comp.getHeight();
}
}
}
And the runnable example...
This goes to the enth degree, creating a specialised component to act as each "fold", but this just reduces the complexity of the API from the outside, meaning, you just need to think about the title and the content and let the rest of the API take care of itself
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private AccordionLayout layout;
public TestPane() {
layout = new AccordionLayout();
setLayout(layout);
AccordionListener listener = new AccordionListener() {
#Override
public void accordionSelected(Component comp) {
layout.setExpanded(comp);
revalidate();
repaint();
}
};
Color colors[] = {Color.RED, Color.BLUE, Color.CYAN, Color.GREEN, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.YELLOW};
String titles[] = {"Red", "Blue", "Cyan", "Green", "Magenta", "Orange", "Pink", "Yellow"};
for (int index = 0; index < colors.length; index++) {
AccordionPanel panel = new AccordionPanel(titles[index], new ContentPane(colors[index]));
panel.setAccordionListener(listener);
add(panel);
}
}
}
public class ContentPane extends JPanel {
public ContentPane(Color background) {
setBackground(background);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(100, 100);
}
}
public interface AccordionListener {
public void accordionSelected(Component comp);
}
public class AccordionPanel extends JPanel {
private JLabel title;
private JPanel header;
private Component content;
private AccordionListener accordionListener;
public AccordionPanel() {
setLayout(new BorderLayout());
title = new JLabel("Title");
header = new JPanel(new FlowLayout(FlowLayout.LEADING));
header.setBackground(Color.GRAY);
header.setBorder(new LineBorder(Color.BLACK));
header.add(title);
add(header, BorderLayout.NORTH);
header.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
AccordionListener listener = getAccordionListener();
if (listener != null) {
listener.accordionSelected(AccordionPanel.this);
}
}
});
}
public AccordionPanel(String title) {
this();
setTitle(title);
}
public AccordionPanel(String title, Component content) {
this(title);
setContentPane(content);
}
public void setAccordionListener(AccordionListener accordionListener) {
this.accordionListener = accordionListener;
}
public AccordionListener getAccordionListener() {
return accordionListener;
}
public void setTitle(String text) {
title.setText(text);
revalidate();
}
public String getText() {
return title.getText();
}
public void setContentPane(Component content) {
if (this.content != null) {
remove(this.content);
}
this.content = content;
if (this.content != null) {
add(this.content);
}
revalidate();
}
public Component getContent() {
return content;
}
#Override
public Dimension getMinimumSize() {
return header.getPreferredSize();
}
#Override
public Dimension getPreferredSize() {
Dimension size = content != null ? content.getPreferredSize() : super.getPreferredSize();
Dimension min = getMinimumSize();
size.width = Math.max(min.width, size.width);
size.height += min.height;
return size;
}
}
public class AccordionLayout implements LayoutManager {
// This "could" be controled by constraints, but that would assume
// that more then one component could be expanded at a time
private Component expanded;
public void setExpanded(Component expanded) {
this.expanded = expanded;
}
public Component getExpanded() {
return expanded;
}
#Override
public void addLayoutComponent(String name, Component comp) {
}
#Override
public void removeLayoutComponent(Component comp) {
}
#Override
public Dimension preferredLayoutSize(Container parent) {
Dimension size = minimumLayoutSize(parent);
if (expanded != null) {
size.height -= expanded.getMinimumSize().height;
size.height += expanded.getPreferredSize().height;
}
return size;
}
#Override
public Dimension minimumLayoutSize(Container parent) {
int height = 0;
int width = 0;
for (Component comp : parent.getComponents()) {
width = Math.max(width, comp.getPreferredSize().width);
height += comp.getMinimumSize().height;
}
return new Dimension(width, height);
}
#Override
public void layoutContainer(Container parent) {
Insets insets = parent.getInsets();
int availableHeight = parent.getHeight() - (insets.top + insets.bottom);
int x = insets.left;
int y = insets.top;
int maxSize = 0;
Dimension minSize = minimumLayoutSize(parent);
if (expanded != null) {
minSize.height -= expanded.getMinimumSize().height;
// Try an honour the preferred size the expanded component...
maxSize = Math.max(expanded.getPreferredSize().height, availableHeight - minSize.height);
}
int width = parent.getWidth() - (insets.left + insets.right);
for (Component comp : parent.getComponents()) {
if (expanded != comp) {
comp.setSize(width, comp.getMinimumSize().height);
} else {
comp.setSize(width, maxSize);
}
comp.setLocation(x, y);
y += comp.getHeight();
}
}
}
}
Now, if you're really up for a challenge, you could use something a animated layout proxy and do something like...
The end goal is to remove older panels when a new panel is added and there isn't enough room for it
I would guess that after you add a panel you compare the preferred height with the actual height. When the preferred height is greater you have a problem and you remove components as required.
So then the next problem is to use a layout manager that doesn't change the heights of the panels. This can still be done with the GridBagLayout. You just need to override the getMinimumSize() method to return the getPreferredSize() Dimension.
Each part of the accordion can open individually and they're of arbitrary size and get added on the fly
You might want to consider using the Relative Layout. You can add components whose preferred size will be respected. So you will be able to check when the preferred height is greater than the actual height.
Then you can also add components that will be sized based on the amount of space left in the panel. These would be your expanding panels.
So in your example you example when you expand an item you could configure that component to take up the entire space available. If you expand two items then they would each get half the space available.
Maybe something like this:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ExpandingPanel extends JPanel
{
private JPanel expanding;
public ExpandingPanel(String text, Color color)
{
setLayout( new BorderLayout() );
JButton button = new JButton( text );
add(button, BorderLayout.NORTH);
expanding = new JPanel();
expanding.setBackground( color );
expanding.setVisible( false );
add(expanding, BorderLayout.CENTER);
button.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
expanding.setVisible( !expanding.isVisible() );
Container parent = ExpandingPanel.this.getParent();
LayoutManager2 layout = (LayoutManager2)parent.getLayout();
if (expanding.isVisible())
layout.addLayoutComponent(ExpandingPanel.this, new Float(1));
else
layout.addLayoutComponent(ExpandingPanel.this, null);
revalidate();
repaint();
}
});
}
private static void createAndShowGUI()
{
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
JPanel content = new JPanel( rl );
content.add( new ExpandingPanel("Red", Color.RED) );
content.add( new ExpandingPanel("Blue", Color.BLUE) );
content.add( new ExpandingPanel("Green", Color.GREEN) );
JFrame frame = new JFrame("Expanding Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( content);
frame.setLocationByPlatform( true );
frame.setSize(200, 300);
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
You can tell something is "crunched" when panel.getPreferredSize().height != panel.getHeight() and panel.getPreferredSize().width != panel.getWidth()
Aim: to place JButton on a top of an image that is loaded from a different class.
Problem: only JButton or image can be displayed
//main class
JPanel mPanel.add(new JButton("ddd") );
mPanel.add(drawbg);
class DrawBg extends JPanel {
public Dimension getPreferredSize() {
return new Dimension(1280, 720);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// background
Image img = new ImageIcon(getClass().getResource("/images/test_bg.jpg")).getImage();
int imgX = img.getWidth(null);
int imgY = img.getHeight(null);
g.drawImage(img, (getWidth() - imgX), (getHeight() - imgY), imgX, imgY, null);
}
Edit Ah yes, as ControlAltDel points out, you're not adding your JButton to your drawing JPanel instance. Just do that, and your problem is solved.
I don't see the bug in your code, so it might lie in code not shown. I do see a problem in that you're reading the image in, inside of paintComponent, something that should never be done as it will slow down painting and thus slow down the perceived responsiveness of your program. Also, why re-read in the image with each paint. Instead read it in once.
For example:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ButtonOnImg extends JPanel {
public static final String IMG_PATH = "https://duke.kenai.com/gun/Gun.jpg";
private BufferedImage img;
public ButtonOnImg() throws IOException {
URL url = new URL(IMG_PATH);
img = ImageIO.read(url);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, null);
}
}
#Override
public Dimension getPreferredSize() {
if (img == null) {
return super.getPreferredSize();
} else {
int w = img.getWidth();
int h = img.getHeight();
return new Dimension(w, h);
}
}
private static void createAndShowGui() {
try {
ButtonOnImg mainPanel = new ButtonOnImg();
mainPanel.add(new JButton("Button!"));
JFrame frame = new JFrame("ButtonOnImg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Which displays as:
I am making a simple program to paint a graph and some points in it. The points should be made with methods while changing coordinates of the g.fillOval but actually its painting only the last point.
Here is the code:
import javax.swing.*;
import java.awt.*;
public class PointGraphWriter extends JPanel
{
JFrame korniza = new JFrame();
private int x;
private int y;
private int length;
private String OX;
private String OY;
private String emri;
private int y_height;
private int x_num;
public PointGraphWriter()
{
int width= 500;
korniza.setSize(width,width);
korniza.setVisible(true);
korniza.setTitle(emri);
korniza.getContentPane().add(this);
}
public void paintComponent(Graphics g)
{
g.drawLine(x,y,x+length,y);
g.drawLine(x,y,x,y-length);
g.drawString(OX,x+length, y+15);
g.drawString(OY,x-15,y-length);
g.drawString("0", x -15,y);
g.drawString("0", x,y+15);
g.fillOval(x_num,y-y_height-2, 4 ,4);
}
public void setTitle(String name)
{
emri= name;
this.repaint();
}
public void setAxes(int x_pos, int y_pos, int axis_length, String x_label, String y_label)
{
x= x_pos;
y=y_pos;
length= axis_length;
OX = x_label;
OY = y_label;
}
public void setPoint1(int height)
{
y_height=height;
x_num = x-2;
this.repaint();
}
public void setPoint2(int height)
{
y_height=height;
x_num = x + length/5-2;
this.repaint();
}
}
and here is the main method:
public class TestPlot
{
public static void main(String[] a)
{
PointGraphWriter e = new PointGraphWriter();
e.setTitle("Graph of y = x*x");
e.setAxes(50, 110, 90, "5", "30");
int scale_factor = 3;
e.setPoint1(0 * scale_factor);
e.setPoint2(1 * scale_factor);
}
}
Please have a look at this example. Something in lines of this, you might have to incorporate in your example, to make it work. Simply use a Collection to store what you have previously painted, and when the new thingy comes along, simply add that thingy to the list, and repaint the whole Collection again. As shown below :
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class RectangleExample {
private DrawingBoard customPanel;
private JButton button;
private Random random;
private java.util.List<Rectangle2D.Double> rectangles;
private ActionListener buttonActions =
new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
Rectangle2D.Double rectangle = new Rectangle2D.Double(
(double) random.nextInt(100), (double) random.nextInt(100),
(double) random.nextInt(100), (double) random.nextInt(100));
rectangles.add(rectangle);
customPanel.setValues(rectangles);
}
};
public RectangleExample() {
rectangles = new ArrayList<Rectangle2D.Double>();
random = new Random();
}
private void displayGUI() {
JFrame frame = new JFrame("Rectangle Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
customPanel = new DrawingBoard();
contentPane.add(customPanel, BorderLayout.CENTER);
button = new JButton("Create Rectangle");
button.addActionListener(buttonActions);
contentPane.add(button, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new RectangleExample().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
class DrawingBoard extends JPanel {
private java.util.List<Rectangle2D.Double> rectangles =
new ArrayList<Rectangle2D.Double>();
public DrawingBoard() {
setOpaque(true);
setBackground(Color.WHITE);
}
public void setValues(java.util.List<Rectangle2D.Double> rectangles) {
this.rectangles = rectangles;
repaint();
}
#Override
public Dimension getPreferredSize() {
return (new Dimension(300, 300));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Rectangle2D.Double rectangle : rectangles) {
g.drawRect((int)rectangle.getX(), (int)rectangle.getY(),
(int)rectangle.getWidth(), (int)rectangle.getHeight());
}
System.out.println("WORKING");
}
}
See Custom Painting Approaches for examples of the two common ways to do painting:
Keep a List of the objects to be painted
Paint onto a BufferedImage
The approach you choose will depend on your exact requirement.
I want to have transparent panels in my GUI (if like Windows 7 window headers, it is better).
Before I have used com.sun.awt.AWTUtilities as
AWTUtilities.setWindowOpacity(frame, (float)0.90);
but its parameter is a window like JFrame and couldn't be used for JPanel.
Also I want to have effects on JPanel or JLabel for example luminescence, as is on Windows 7 header buttons. Any other interesting effect is also helpful for me.
Please see the tutorials How to Create Translucent and Shaped Windows and* How to Create Translucent and Shaped Windows*. Follow the links to excellent example depots by #camickr.
For example,
import java.awt.event.*;
import java.awt.Color;
import java.awt.AlphaComposite;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
public class ButtonTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ButtonTest().createAndShowGUI();
}
});
}
private JFrame frame;
private JButton opaqueButton1;
private JButton opaqueButton2;
private SoftJButton softButton1;
private SoftJButton softButton2;
public void createAndShowGUI() {
opaqueButton1 = new JButton("Opaque Button");
opaqueButton2 = new JButton("Opaque Button");
softButton1 = new SoftJButton("Transparent Button");
softButton2 = new SoftJButton("Transparent Button");
opaqueButton1.setBackground(Color.GREEN);
softButton1.setBackground(Color.GREEN);
frame = new JFrame();
frame.getContentPane().setLayout(new java.awt.GridLayout(2, 2, 10, 10));
frame.add(opaqueButton1);
frame.add(softButton1);
frame.add(opaqueButton2);
frame.add(softButton2);
frame.setSize(567, 350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Timer alphaChanger = new Timer(30, new ActionListener() {
private float incrementer = -.03f;
#Override
public void actionPerformed(ActionEvent e) {
float newAlpha = softButton1.getAlpha() + incrementer;
if (newAlpha < 0) {
newAlpha = 0;
incrementer = -incrementer;
} else if (newAlpha > 1f) {
newAlpha = 1f;
incrementer = -incrementer;
}
softButton1.setAlpha(newAlpha);
softButton2.setAlpha(newAlpha);
}
});
alphaChanger.start();
Timer uiChanger = new Timer(3500, new ActionListener() {
private LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels();
private int index = 1;
#Override
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(laf[index].getClassName());
SwingUtilities.updateComponentTreeUI(frame);
} catch (Exception exc) {
exc.printStackTrace();
}
index = (index + 1) % laf.length;
}
});
uiChanger.start();
}
public static class SoftJButton extends JButton {
private static final JButton lafDeterminer = new JButton();
private static final long serialVersionUID = 1L;
private boolean rectangularLAF;
private float alpha = 1f;
public SoftJButton() {
this(null, null);
}
public SoftJButton(String text) {
this(text, null);
}
public SoftJButton(String text, Icon icon) {
super(text, icon);
setOpaque(false);
setFocusPainted(false);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
#Override
public void paintComponent(java.awt.Graphics g) {
java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
if (rectangularLAF && isBackgroundSet()) {
Color c = getBackground();
g2.setColor(c);
g.fillRect(0, 0, getWidth(), getHeight());
}
super.paintComponent(g2);
}
#Override
public void updateUI() {
super.updateUI();
lafDeterminer.updateUI();
rectangularLAF = lafDeterminer.isOpaque();
}
}
}
If you have time I recommend you go through this Filty Rich Clients. By using this book you can learn to create stunning visual and animated effects with Swing and Java 2D. Learn graphics and animation fundamentals as well as advanced rendering techniques.
EDIT:
To creat transparent panels call
setOpaque(false)
It'll pass off painting the background to its parent, which may draw its own background.
You can do a screen capture and then use that to paint the background of the panel.