Scale the ImageIcon automatically to label size - java

On my JFrame, I am using the following code to display an image on the Panel :
ImageIcon img= new ImageIcon("res.png");
jLabel.setIcon(img);
I would like to "auto-size" the picture in the label. Indeed, sometimes the image size is only few pixel, sometimes well more.
Is there a way to set the size of the label, and then to autosize the image in the label?

This is a tricky question. You highlight the fact that you are using a JLabel to show the image, which is the standard way of doing things, but, JLabel is a complex little beast, with text, icon and text alignment and positioning.
If you don't need all that extra functionality, I would simply create yourself a custom component capable of painting a scaled image...
The next question is, how do you want to scale the image? Do you want to maintain the aspect ratio of the image? Do you want to "fit" or "fill" the image to the available space.
#David is right. You should, where possible, avoid Image#getScaledInstance as it's not the fastest, but, more importantly, generally, it doesn't provide the highest quality either.
Fit vs Fill
The following example is rather simple (and borrows heavy from my library of code, so it's probably also a little convoluted ;)). It could use from a background scaling thread, but I would base the decision on the potential size of original image.
public class ResizableImage {
public static void main(String[] args) {
new ResizableImage();
}
public ResizableImage() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
try {
BufferedImage image = ImageIO.read(new File("/path/to/your/image"));
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ScalablePane(image));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (Exception exp) {
exp.printStackTrace();
}
}
});
}
public class ScalablePane extends JPanel {
private Image master;
private boolean toFit;
private Image scaled;
public ScalablePane(Image master) {
this(master, true);
}
public ScalablePane(Image master, boolean toFit) {
this.master = master;
setToFit(toFit);
}
#Override
public Dimension getPreferredSize() {
return master == null ? super.getPreferredSize() : new Dimension(master.getWidth(this), master.getHeight(this));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Image toDraw = null;
if (scaled != null) {
toDraw = scaled;
} else if (master != null) {
toDraw = master;
}
if (toDraw != null) {
int x = (getWidth() - toDraw.getWidth(this)) / 2;
int y = (getHeight() - toDraw.getHeight(this)) / 2;
g.drawImage(toDraw, x, y, this);
}
}
#Override
public void invalidate() {
generateScaledInstance();
super.invalidate();
}
public boolean isToFit() {
return toFit;
}
public void setToFit(boolean value) {
if (value != toFit) {
toFit = value;
invalidate();
}
}
protected void generateScaledInstance() {
scaled = null;
if (isToFit()) {
scaled = getScaledInstanceToFit(master, getSize());
} else {
scaled = getScaledInstanceToFill(master, getSize());
}
}
protected BufferedImage toBufferedImage(Image master) {
Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this));
BufferedImage image = createCompatibleImage(masterSize);
Graphics2D g2d = image.createGraphics();
g2d.drawImage(master, 0, 0, this);
g2d.dispose();
return image;
}
public Image getScaledInstanceToFit(Image master, Dimension size) {
Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this));
return getScaledInstance(
toBufferedImage(master),
getScaleFactorToFit(masterSize, size),
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
true);
}
public Image getScaledInstanceToFill(Image master, Dimension size) {
Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this));
return getScaledInstance(
toBufferedImage(master),
getScaleFactorToFill(masterSize, size),
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
true);
}
public Dimension getSizeToFit(Dimension original, Dimension toFit) {
double factor = getScaleFactorToFit(original, toFit);
Dimension size = new Dimension(original);
size.width *= factor;
size.height *= factor;
return size;
}
public Dimension getSizeToFill(Dimension original, Dimension toFit) {
double factor = getScaleFactorToFill(original, toFit);
Dimension size = new Dimension(original);
size.width *= factor;
size.height *= factor;
return size;
}
public double getScaleFactor(int iMasterSize, int iTargetSize) {
return (double) iTargetSize / (double) iMasterSize;
}
public double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
public double getScaleFactorToFill(Dimension masterSize, Dimension targetSize) {
double dScaleWidth = getScaleFactor(masterSize.width, targetSize.width);
double dScaleHeight = getScaleFactor(masterSize.height, targetSize.height);
return Math.max(dScaleHeight, dScaleWidth);
}
public BufferedImage createCompatibleImage(Dimension size) {
return createCompatibleImage(size.width, size.height);
}
public BufferedImage createCompatibleImage(int width, int height) {
GraphicsConfiguration gc = getGraphicsConfiguration();
if (gc == null) {
gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
BufferedImage image = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
image.coerceData(true);
return image;
}
protected BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) {
BufferedImage imgScale = img;
int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);
if (dScaleFactor <= 1.0d) {
imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);
} else {
imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);
}
return imgScale;
}
protected BufferedImage getScaledDownInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality) {
int type = (img.getTransparency() == Transparency.OPAQUE)
? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
if (targetHeight > 0 || targetWidth > 0) {
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
} else {
ret = new BufferedImage(1, 1, type);
}
return ret;
}
protected BufferedImage getScaledUpInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint,
boolean higherQuality) {
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
int w, h;
if (higherQuality) {
// Use multi-step technique: start with original size, then
// scale down in multiple passes with drawImage()
// until the target size is reached
w = img.getWidth();
h = img.getHeight();
} else {
// Use one-step technique: scale directly from original
// size to target size with a single drawImage() call
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w < targetWidth) {
w *= 2;
if (w > targetWidth) {
w = targetWidth;
}
}
if (higherQuality && h < targetHeight) {
h *= 2;
if (h > targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
tmp = null;
} while (w != targetWidth || h != targetHeight);
return ret;
}
}
}

Is there a way to set the size of the label
Override getPreferredSize() of JLabel and return the Dimensions you want,
but because a JLabel will size itself to its content you will just need to resize the picture you add to the JLabel.
and then to autosize the image in the label?
You will have to resize your image according to the width and height you want (than simply add it to the JLabel and the JLabel will size to fit the image).
I do not recommend Image.getScaledInstance(..) have a read here for more:
The Perils of Image.getScaledInstance()
Mainly the problem outlined is:
Image.getScaledInstance() does not return a finished, scaled image. It
leaves much of the scaling work for a later time when the image pixels
are used.
Here is a custom method Ive been using to circumvent the issues created by getScaledInstance:
public static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
}
you would create an image to whatever size you want via:
BufferedImage image=ImageIO.read(..);
BufferedImage resizedImage=resize(image,100,100);//resize the image to 100x100

It can also be done by overriding the paintComponent method of JLabel and drawing the image having width and height as that of JLabel. And if you wish to resize the image when the parent container is resized you can apply the WindowListener on the parent container and repaint the Jlabel instance each time the parent container is resized.
Here is the Demo:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class LabelDemo extends JFrame
{
ImageIcon imageIcon;
MyJLabel jLabel ;
public LabelDemo ()
{
super("JLabel Demo");
}
public void createAndShowGUI()
{
imageIcon = new ImageIcon("apple.png");
jLabel = new MyJLabel(imageIcon);
getContentPane().add(jLabel);
addWindowListener( new WindowAdapter()
{
public void windowResized(WindowEvent evt)
{
jLabel.repaint();
}
});
setSize(300,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
jLabel.repaint();
}
public static void main(String st[])
{
SwingUtilities.invokeLater( new Runnable()
{
#Override
public void run()
{
LabelDemo demo = new LabelDemo();
demo.createAndShowGUI();
}
});
}
}
class MyJLabel extends JLabel
{
ImageIcon imageIcon;
public MyJLabel(ImageIcon icon)
{
super();
this.imageIcon = icon;
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(imageIcon.getImage(),0,0,getWidth(),getHeight(),this);
}
}

You can use the Stretch Icon.
The image will automatically be resized to fill the space available to the label. You can control whether the image is scaled proportionally or completely fills the area.
Using the StretchIcon is more flexible than doing custom painting as suggested in the other links as you can benefit from the automatic resizing on any component that supports an Icon.
StretchIcon.java:
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.net.URL;
import javax.swing.ImageIcon;
/**
* An <CODE>Icon</CODE> that scales its image to fill the component area, excluding any border or insets, optionally maintaining the image's
* aspect ratio by padding and centering the scaled image horizontally or vertically.
* <P>
* The class is a drop-in replacement for <CODE>ImageIcon</CODE>, except that the no-argument constructor is not supported.
* <P>
* As the size of the Icon is determined by the size of the component in which it is displayed, <CODE>StretchIcon</CODE> must only be used
* in conjunction with a component and layout that does not depend on the size of the component's Icon.
*
* #version 1.1 01/15/2016
* #author Darryl
*/
public class StretchIcon extends ImageIcon
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Determines whether the aspect ratio of the image is maintained. Set to <code>false</code> to allow th image to distort to fill the
* component.
*/
protected boolean proportionate = true;
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes.
*
* #param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
*
* #see ImageIcon#ImageIcon(byte[])
*/
public StretchIcon(byte[] imageData)
{
super(imageData);
}
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes with the specified behavior.
*
* #param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(byte[])
*/
public StretchIcon(byte[] imageData, boolean proportionate)
{
super(imageData);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes.
*
* #param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* #param description a brief textual description of the image
*
* #see ImageIcon#ImageIcon(byte[], java.lang.String)
*/
public StretchIcon(byte[] imageData, String description)
{
super(imageData, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from an array of bytes with the specified behavior.
*
* #see ImageIcon#ImageIcon(byte[])
* #param imageData an array of pixels in an image format supported by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG
* #param description a brief textual description of the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(byte[], java.lang.String)
*/
public StretchIcon(byte[] imageData, String description, boolean proportionate)
{
super(imageData, description);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image.
*
* #param image the image
*
* #see ImageIcon#ImageIcon(java.awt.Image)
*/
public StretchIcon(Image image)
{
super(image);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image with the specified behavior.
*
* #param image the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.awt.Image)
*/
public StretchIcon(Image image, boolean proportionate)
{
super(image);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image.
*
* #param image the image
* #param description a brief textual description of the image
*
* #see ImageIcon#ImageIcon(java.awt.Image, java.lang.String)
*/
public StretchIcon(Image image, String description)
{
super(image, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the image with the specified behavior.
*
* #param image the image
* #param description a brief textual description of the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.awt.Image, java.lang.String)
*/
public StretchIcon(Image image, String description, boolean proportionate)
{
super(image, description);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file.
*
* #param filename a String specifying a filename or path
*
* #see ImageIcon#ImageIcon(java.lang.String)
*/
public StretchIcon(String filename)
{
super(filename);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file with the specified behavior.
*
* #param filename a String specifying a filename or path
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.lang.String)
*/
public StretchIcon(String filename, boolean proportionate)
{
super(filename);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file.
*
* #param filename a String specifying a filename or path
* #param description a brief textual description of the image
*
* #see ImageIcon#ImageIcon(java.lang.String, java.lang.String)
*/
public StretchIcon(String filename, String description)
{
super(filename, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified file with the specified behavior.
*
* #param filename a String specifying a filename or path
* #param description a brief textual description of the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.awt.Image, java.lang.String)
*/
public StretchIcon(String filename, String description, boolean proportionate)
{
super(filename, description);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL.
*
* #param location the URL for the image
*
* #see ImageIcon#ImageIcon(java.net.URL)
*/
public StretchIcon(URL location)
{
super(location);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL with the specified behavior.
*
* #param location the URL for the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.net.URL)
*/
public StretchIcon(URL location, boolean proportionate)
{
super(location);
this.proportionate = proportionate;
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL.
*
* #param location the URL for the image
* #param description a brief textual description of the image
*
* #see ImageIcon#ImageIcon(java.net.URL, java.lang.String)
*/
public StretchIcon(URL location, String description)
{
super(location, description);
}
/**
* Creates a <CODE>StretchIcon</CODE> from the specified URL with the specified behavior.
*
* #param location the URL for the image
* #param description a brief textual description of the image
* #param proportionate <code>true</code> to retain the image's aspect ratio, <code>false</code> to allow distortion of the image to
* fill the component.
*
* #see ImageIcon#ImageIcon(java.net.URL, java.lang.String)
*/
public StretchIcon(URL location, String description, boolean proportionate)
{
super(location, description);
this.proportionate = proportionate;
}
/**
* Paints the icon. The image is reduced or magnified to fit the component to which it is painted.
* <P>
* If the proportion has not been specified, or has been specified as <code>true</code>, the aspect ratio of the image will be preserved
* by padding and centering the image horizontally or vertically. Otherwise the image may be distorted to fill the component it is
* painted to.
* <P>
* If this icon has no image observer,this method uses the <code>c</code> component as the observer.
*
* #param c the component to which the Icon is painted. This is used as the observer if this icon has no image observer
* #param g the graphics context
* #param x not used.
* #param y not used.
*
* #see ImageIcon#paintIcon(java.awt.Component, java.awt.Graphics, int, int)
*/
#Override
public synchronized void paintIcon(Component c, Graphics g, int x, int y)
{
Image image = getImage();
if (image == null)
{
return;
}
Insets insets = ((Container) c).getInsets();
x = insets.left;
y = insets.top;
int w = c.getWidth() - x - insets.right;
int h = c.getHeight() - y - insets.bottom;
if (proportionate)
{
int iw = image.getWidth(c);
int ih = image.getHeight(c);
if ((iw * h) < (ih * w))
{
iw = (h * iw) / ih;
x += (w - iw) / 2;
w = iw;
}
else
{
ih = (w * ih) / iw;
y += (h - ih) / 2;
h = ih;
}
}
ImageObserver io = getImageObserver();
/*
* Added this code to generate nicer looking results when scaling. - bspkrs
* BEGIN CHANGES
*/
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, w, h, io == null ? c : io);
g2d.dispose();
/*
* END CHANGES
*/
g.drawImage(bi, x, y, w, h, io == null ? c : io);
}
/**
* Overridden to return 0. The size of this Icon is determined by the size of the component.
*
* #return 0
*/
#Override
public int getIconWidth()
{
return 0;
}
/**
* Overridden to return 0. The size of this Icon is determined by the size of the component.
*
* #return 0
*/
#Override
public int getIconHeight()
{
return 0;
}
}

Try this function:
public static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
}
BufferedImage image1=ImageIO.read(url.openStream());
BufferedImage resizedImage=resize(image,100,100);
System.out.println("Load image into frame...");
icon=new ImageIcon(resizedImage);

private Image fitimage(Image img, int w, int h) {
int width = img.getWidth(this);
int height = img.getHeight(this);
BufferedImage resizedimage;
if (width > w && height > h) {
resizedimage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedimage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, 0, 0, w, h, null);
g2.dispose();
} else {
resizedimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedimage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, 0, 0, width, height, null);
g2.dispose();
}
return resizedimage;
}

easywayprogramming.com how to resize imageicon in java
When we apply image icon to any component like button, label or panel, it not apply properly because of size of that image. We can resize that image icon in two ways.
first way:
Image img = myIcon2.getImage(); Image newimg = img.getScaledInstance(230, 310, java.awt.Image.SCALE_SMOOTH);
newIcon = new ImageIcon(newimg);
second way:
Image img = myIcon2.getImage(); BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
newIcon = new ImageIcon(bi);
Try following link easywayprogramming.blogspot.in:
easywayprogramming.blogspot.in ho to resize image icon in java

Related

Troubles converting SVG subset to Java with java tool

I am using this tool:
https://github.com/codenameone/flamingo-svg-transcoder
you can read more about it here:
https://www.codenameone.com/blog/flamingo-svg-transcoder.html#commento-login-box-container
I used it to convert a svg file and this is the result:
/**
* This class has been automatically generated using
* Flamingo SVG transcoder.
*/
public class MyImageFromSVGSubset extends com.codename1.ui.Image implements Painter {
private int width, height;
private Transform t = Transform.makeIdentity(), t2 = Transform.makeIdentity();
public MyImageFromSVGSubset() {
super(null);
width = getOrigWidth();
height = getOrigHeight();
}
public MyImageFromSVGSubset(int width, int height) {
super(null);
this.width = width;
this.height = height;
fixAspectRatio();
}
#Override
public int getWidth() {
return width;
}
#Override
public int getHeight() {
return height;
}
#Override
public void scale(int width, int height) {
this.width = width;
this.height = height;
fixAspectRatio();
}
#Override
public MyImageFromSVGSubset scaled(int width, int height) {
MyImageFromSVGSubset f = new MyImageFromSVGSubset(width, height);
f.fixAspectRatio();
return f;
}
public Image toImage() {
Image i = Image.createImage(width, height, 0);
Graphics g = i.getGraphics();
drawImage(g, null, 0, 0, width, height);
return i;
}
private void fixAspectRatio() {
if(width == -1) {
float ar = ((float)getOrigWidth()) / ((float)getOrigHeight());
width = Math.round(((float)height) * ar);
}
if (height == -1) {
float ar = ((float)getOrigHeight()) / ((float)getOrigWidth());
height = Math.round(((float)width) * ar);
}
}
#Override
public Image fill(int width, int height) {
return new MyImageFromSVGSubset(width, height);
}
#Override
public Image applyMask(Object mask) {
return new MyImageFromSVGSubset(width, height);
}
#Override
public boolean isAnimation() {
return true;
}
#Override
public boolean requiresDrawImage() {
return true;
}
#Override
protected void drawImage(Graphics g, Object nativeGraphics, int x, int y) {
drawImage(g, nativeGraphics, x, y, width, height);
}
#Override
protected void drawImage(Graphics g, Object nativeGraphics, int x, int y, int w, int h) {
g.getTransform(t);
t2.setTransform(t);
float hRatio = ((float) w) / ((float) getOrigWidth());
float vRatio = ((float) h) / ((float) getOrigHeight());
t2.translate(x + g.getTranslateX(), y + g.getTranslateY());
t2.scale(hRatio, vRatio);
g.setTransform(t2);
paint(g);
g.setTransform(t);
}
private static void paint(Graphics g) {
int origAlpha = g.getAlpha();
Stroke baseStroke;
Shape shape;
g.setAntiAliased(true);
g.setAntiAliasedText(true);
/*Composite origComposite = g.getComposite();
if (origComposite instanceof AlphaComposite) {
AlphaComposite origAlphaComposite = (AlphaComposite)origComposite;
if (origAlphaComposite.getRule() == AlphaComposite.SRC_OVER) {
origAlpha = origAlphaComposite.getAlpha();
}
}
*/
java.util.LinkedList<Transform> transformations = new java.util.LinkedList<Transform>();
//
transformations.push(g.getTransform());
g.transform(new AffineTransform(3.7795277f, 0, 0, 3.7795277f, 0, 0).toTransform());
// _0
// _0_0
// _0_0_0
shape = new Rectangle2D(0.008569182828068733, 0.0054579987190663815, 6.3905863761901855, 6.390747547149658);
g.setColor(0xffffff);
g.fillShape(shape);
// _0_0_1
shape = new GeneralPath();
((GeneralPath) shape).moveTo(5.0011573, 1.454892);
((GeneralPath) shape).curveTo(4.914109, 1.454892, 4.8439946, 1.526065, 4.8439946, 1.6128483);
...
...
//very long sequence of graphical instructions that corresponds to the actual drawing
...
...
((GeneralPath) shape).closePath();
g.fillShape(shape);
g.setTransform(transformations.pop()); // _0
g.setAlpha(origAlpha);
}
/**
* Returns the X of the bounding box of the original SVG image.
*
* #return The X of the bounding box of the original SVG image.
*/
public static int getOrigX() {
return 1;
}
/**
* Returns the Y of the bounding box of the original SVG image.
*
* #return The Y of the bounding box of the original SVG image.
*/
public static int getOrigY() {
return 1;
}
/**
* Returns the width of the bounding box of the original SVG image.
*
* #return The width of the bounding box of the original SVG image.
*/
public static int getOrigWidth() {
return 24;
}
/**
* Returns the height of the bounding box of the original SVG image.
*
* #return The height of the bounding box of the original SVG image.
*/
public static int getOrigHeight() {
return 24;
}
#Override
public void paint(Graphics g, Rectangle rect) {
drawImage(g, null, rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
}
}
It's Java code to be used in my application (Codename One) but it doesn't work for me.
I put the following code into a working layout:
button.setIcon(new MyImageFromSVGSubset(256,256));
The image is present because it occupies the right space (256x256) but nothing is drawn.
What is the mistake?

Text Being Duplicated in a JLabel

I'm designing an application for configuring a pallet, and I've got a class that extends JLabel which I use to create JLabels with rotated text. I've found a few examples online of how to do this and my rotation is working well enough, its not perfect but it's a work in progress.
The problem I have at the moment is that the text in my rotated JLabels is duplicated, and I don't know why. Below is a picture showing the duplicate text in each label, its more prominent in some than in others, eg with the height label the duplication can clearly be seen.
Duplicate Label Text Image:
Here's the source code for my RotatableText class that extends JLabel.
public class RotatableText extends JLabel
{
private static final long serialVersionUID = 1L;
private String text;
private double angle;
public final static String DEGREES = "deg";
public final static String RADIANS = "rad";
private final static double TO_RADIANS = Math.PI/180;
private final static double TO_DEGREES = 180/Math.PI;
/**
* Creates text rotated by angle in a clockwise direction if clockwise is true,
* or anti-clockwise if it's false
* #param angle angle to be rotated by in degrees
* #param clockwise determines direction of rotation#exception Exception if angleUnit is not RotatableText.DEGREES or RotatableText.RADIANS
*/
public RotatableText(String text, double angle, boolean clockwise, final String angleUnit) throws IllegalAngleUnitException
{
if (!(angleUnit.equals(DEGREES) || angleUnit.equals(RADIANS)))
{
throw new IllegalAngleUnitException("Invalid Angle Selected");
}
else if (angleUnit.equals(DEGREES))
{
if (!clockwise)
{
this.angle = -angle * TO_RADIANS;
super.setText(text);
}
else
{
this.angle = angle * TO_RADIANS;
super.setText(text);
}
}
else if (angleUnit.equals(RADIANS))
{
if (!clockwise)
{
this.angle = -angle;
super.setText(text);
}
else
{
this.angle = angle;
super.setText(text);
}
}
setVerticalAlignment(JLabel.TOP);
setHorizontalAlignment(JLabel.LEFT);
}
/**
* Creates text rotated by angle in an anti-clockwise rotation
* #param angle angle to be rotated by in degrees
* #exception Exception if angleUnit is not RotatableText.DEGREES or RotatableText.RADIANS
*/
public RotatableText(String text, double angle, final String angleUnit) throws IllegalAngleUnitException
{
if (!(angleUnit.equals(DEGREES) || angleUnit.equals(RADIANS)))
{
throw new IllegalAngleUnitException("Invalid Angle Selected");
}
else if (angleUnit.equals(DEGREES))
{
this.angle = angle * TO_RADIANS;
super.setText(text);
}
else if (angleUnit.equals(RADIANS))
{
this.angle = angle;
super.setText(text);
}
setVerticalAlignment(JLabel.BOTTOM);
setHorizontalAlignment(JLabel.CENTER);
}
/**
* Draws the Component
*/
#Override
protected void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
g2.rotate(angle, getPreferredSize().width/2, getPreferredSize().height/2);
g2.drawString(super.getText(), 0, 0);
setBounds(getX(), getY());
super.paintComponent(g);
}
/**
* Gets the text of this RotatableText.
* #return text
*/
public String getText()
{
return super.getText();
}
/**
* Set's bounds with a fixed size
*/
public void setBounds(int x, int y)
{
super.setBounds(x, y, 100, 100);
}
public void setText(String text)
{
super.setText(text);
repaint();
}
/**
* Set the angle of this RotatableText in Radians
* #param angle
*/
public void setAngle(double angle)
{
this.angle = angle;
repaint();
}
/**
* Sets the angle of this RotatableText in the specified unit
* #param angle
* #param angleUnit
* #throws IllegalAngleUnitException
*/
public void setAngle(double angle, String angleUnit) throws IllegalAngleUnitException
{
if (!(angleUnit.equals(DEGREES) || angleUnit.equals(RADIANS)))
{
throw new IllegalAngleUnitException("Invalid Angle Selected");
}
else if (angleUnit.equals(DEGREES))
{
this.angle = angle * TO_RADIANS;
}
else if (angleUnit.equals(RADIANS))
{
this.angle = angle;
}
repaint();
}
/**
* Gets the angle of this RotatableText, anti-clockwise from the horizontal, in degrees.
* #return
*/
public double getAngle()
{
return angle * TO_DEGREES;
}
}
Each Label is generated as follows (this is the length label)
lengthLabel = new RotatableText("0", 14, true, RotatableText.DEGREES);
Each label is updated by passing getting the text from its respective text field and passing it as an argument for label.setText().
EDIT: printing System.out.println(heightLabel.getText()) prints just one copy of the text.
If anyone has an idea as to why this duplication is occuring, I'd love to hear them.
Thanks,
Sam.
You're drawing your text twice in your code as indicated below:
#Override
protected void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
g2.rotate(angle, getPreferredSize().width/2, getPreferredSize().height/2);
g2.drawString(super.getText(), 0, 0); // ****** here *****
setBounds(getX(), getY());
super.paintComponent(g); // ******* here ******
}
Also, I wouldn't set a component's bounds in a painting method, a dangerous thing to do, but do consider setting the Graphics2D clip there. Also I would do my rotation on a copy of the Graphics object, and then dispose of the copy when done. Otherwise you risk propagating rotational side effects downstream in the painting chain (if not desired)
e.g.,
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.rotate(angle, getPreferredSize().width / 2, getPreferredSize().height / 2);
// g2.drawString(super.getText(), 0, 0);
// setBounds(getX(), getY());
// ***** This is a kludge and needs to be calculated better ****
Rectangle clipBounds = g2.getClipBounds();
int extraBounds = 10;
int x = clipBounds.x - extraBounds;
int y = clipBounds.y - extraBounds;
int width = clipBounds.width + 2 * extraBounds;
int height = clipBounds.height + 2 * extraBounds;
g2.setClip(x, y, width, height);
// ***** end kludge
super.paintComponent(g2);
g2.dispose();
}

Canvas shows content only by minimizing and resizing the window

im using the Canvas class to make a screensaver as a schoolproject.
But the window generated by Canvas doesnt show my objects on it (current time)
until i minimize it an resize it again. After that all things works fine.
so what is wrong?
thank you for coming answers!
with kind regards
leon
those are the classes, i peronally think that the problem is in the class Start or BufferedCanvas
import java.awt.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Start
{
int fensterX = 900;
int fensterY = 700;
Farbengenerator fg = new Farbengenerator();
BufferedCanvas c =newBufferedCanvas("Bild",fensterX,fensterY);
Zeit z = new Zeit();
SchriftParameter sp = new SchriftParameter();
public void zeichneText(){
double x = 100;
double y = 100;
double fy =0.01;
double fx =0.02;
int red=0;
int green=0;
int blue=0;
double colourGrowRate=0.05;
String uhr;
c.setFont(sp.setzteSchrift());
c.setForegroundColour(Color.BLACK);
c.setBackgroundColour(Color.WHITE);
for(int i=0;i<100;i++){
c.drawString("Starting...",(int)x,(int)y);
c.updateAndShow();
try{Thread.sleep(50);}
catch(Exception e){};
c.updateAndShow();
}
CreateButton d = new CreateButton();
d.run();
while(true) {
c.erase();
uhr = z.erstelleZeit();
c.drawString(uhr,(int)x,(int)y);
if((int)x >fensterX-93 || (int)x <5){
fx = fx * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)y > fensterY-1 || (int)y < 46){
fy = fy * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)colourGrowRate>=1){
fg.generiereFarbe();
colourGrowRate = 0.05;
}
colourGrowRate=colourGrowRate+colourGrowRate;
x = x + fx;
y = y + fy;
c.updateAndShow();
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;
public class BufferedCanvas
{
private JFrame frame;
private CanvasPane canvas;
private Graphics2D graphic;
private Color backgroundColour;
private Image canvasImage;
BufferStrategy buff;
/**
* Create a BufferedCanvas with default height,
width and background colour
* (300, 300, white).
* #param title title to appear in Canvas Frame
*/
public BufferedCanvas(String title)
{
this(title, 300, 300, Color.white);
}
/**
* Create a BufferedCanvas with default background colour (white).
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
*/
public BufferedCanvas(String title, int width, int height)
{
this(title, width, height, Color.white);
}
/**
* Create a BufferedCanvas.
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
* #param bgClour the desired background colour of the canvas
*/
public BufferedCanvas(String title, int width, int height, Color bgColour)
{
frame = new JFrame();
canvas = new CanvasPane();
frame.setContentPane(canvas);
frame.setTitle(title);
canvas.setPreferredSize(new Dimension(width, height));
backgroundColour = bgColour;
frame.pack();
frame.createBufferStrategy(2);
buff = frame.getBufferStrategy();
graphic = (Graphics2D)buff.getDrawGraphics();
setVisible(true);
}
/**
* Set the canvas visibility and brings canvas to the front of screen
* when made visible. This method can also be used to bring an already
* visible canvas to the front of other windows.
* #param visible boolean value representing the desired visibility of
* the canvas (true or false)
*/
public void setVisible(boolean visible)
{
if(graphic == null) {
// first time: instantiate the offscreen image and fill it with
// the background colour
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColour);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(true);
}
/**
* Update the canvas and show the new image.
*/
public void updateAndShow(){
buff.show();
}
/**
* Provide information on visibility of the Canvas.
* #return true if canvas is visible, false otherwise
*/
public boolean isVisible()
{
return frame.isVisible();
}
/**
* Draw a given shape onto the canvas.
* #param shape the shape object to be drawn on the canvas
*/
public void draw(Shape shape)
{
graphic.draw(shape);
//canvas.repaint();
}
/**
* Fill the internal dimensions of a given shape with the current
* foreground colour of the canvas.
* #param shape the shape object to be filled
*/
public void fill(Shape shape)
{
graphic.fill(shape);
//canvas.repaint();
}
/**
* Erase the whole canvas.
*/
public void erase()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erase a given shape's interior on the screen.
* #param shape the shape object to be erased
*/
public void erase(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.fill(shape); // erase by filling background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erases a given shape's outline on the screen.
* #param shape the shape object to be erased
*/
public void eraseOutline(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.draw(shape); // erase by drawing background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws an image onto the canvas.
* #param image the Image object to be displayed
* #param x x co-ordinate for Image placement
* #param y y co-ordinate for Image placement
* #return returns boolean value representing whether the image was
* completely loaded
*/
public boolean drawImage(Image image, int x, int y)
{
boolean result = graphic.drawImage(image, x, y, null);
//canvas.repaint();
return result;
}
/**
* Draws a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void drawString(String text, int x, int y)
{
graphic.drawString(text, x, y);
//canvas.repaint();
}
/**
* Erases a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void eraseString(String text, int x, int y)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.drawString(text, x, y);
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws a line on the Canvas.
* #param x1 x co-ordinate of start of line
* #param y1 y co-ordinate of start of line
* #param x2 x co-ordinate of end of line
* #param y2 y co-ordinate of end of line
*/
public void drawLine(int x1, int y1, int x2, int y2)
{
graphic.drawLine(x1, y1, x2, y2);
//canvas.repaint();
}
/**
* Draws a dot/pixel on the Canvas.
* #param x x co-ordinate of dot
* #param y y co-ordinate of dot
*/
public void drawDot(int x, int y)
{
graphic.drawLine(x, y, x, y);
//canvas.repaint();
}
/**
* Sets the foreground colour of the Canvas.
* #param newColour the new colour for the foreground of the Canvas
*/
public void setForegroundColour(Color newColour)
{
graphic.setColor(newColour);
}
/**
* Returns the current colour of the foreground.
* #return the colour of the foreground of the Canvas
*/
public Color getForegroundColour()
{
return graphic.getColor();
}
/**
* Sets the background colour of the Canvas.
* #param newColour the new colour for the background of the Canvas
*/
public void setBackgroundColour(Color newColour)
{
backgroundColour = newColour;
graphic.setBackground(newColour);
}
/**
* Returns the current colour of the background
* #return the colour of the background of the Canvas
*/
public Color getBackgroundColour()
{
return backgroundColour;
}
/**
* changes the current Font used on the Canvas
* #param newFont new font to be used for String output
*/
public void setFont(Font newFont)
{
graphic.setFont(newFont);
}
/**
* Returns the current font of the canvas.
* #return the font currently in use
**/
public Font getFont()
{
return graphic.getFont();
}
/**
* Sets the size of the canvas.
* #param width new width
* #param height new height
*/
public void setSize(int width, int height)
{
canvas.setPreferredSize(new Dimension(width, height));
Image oldImage = canvasImage;
canvasImage = canvas.createImage(width, height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.drawImage(oldImage, 0, 0, null);
frame.pack();
}
/**
* Returns the size of the canvas.
* #return The current dimension of the canvas
*/
public Dimension getSize()
{
return canvas.getSize();
}
/**
* Waits for a specified number of milliseconds before finishing.
* This provides an easy way to specify a small delay which can be
* used when producing animations.
* #param milliseconds the number
*/
public void wait(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (Exception e)
{
// ignoring exception at the moment
}
}
/************************************************************************
* Nested class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class CreateButton extends JFrame implements ActionListener{
public void run() {
createAndShowGUI();
}
public CreateButton() {
// set layout for the frame
this.getContentPane().setLayout(new FlowLayout());
JButton button1 = new JButton();
button1.setText("closeApp");
//set actionlisteners for the buttons
button1.addActionListener(this);
// define a custom short action command for the button
button1.setActionCommand("closeApp");
// add buttons to frame
add(button1);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new CreateButton();
//Display the window.
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent ae) {
String action = ae.getActionCommand();
if (action.equals("closeApp")) {
System.exit(1);
}
}
}
import java.awt.*;
public class SchriftParameter
{
public Font setzteSchrift(){
Font f = new Font("Fixed",1,24);
return (f);
}
}
public class Farbengenerator
{
int r=0;
int g=0;
int b=0;
public void generiereFarbe(){
if (r<255&&g==0&&b==0){
r++;
}
else if (r==255&&g<255&&b==0){
g++;
}
else if (r>0&&g==255&&b==0){
r= r-1;
}
else if (r==0&&g==255&&b<255){
b++;
}
else if (r==0&&g>0&&b==255){
g=g-1;
}
else if (r<255&&g==0&&b==255){
r++;
}
else if (r==255&&g==0&&b>0){
b=b-1;
}
}
public int gibROT () {
return(r);
}
public int gibGRUEN () {
return(g);
}
public int gibBLAU () {
return(b);
}
}
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Zeit
{
public String erstelleZeit(){
DateFormat df = new SimpleDateFormat("HH:mm:ss");
Date d = new Date();
String uhr = df.format(d);
return (uhr);
}
}

IntelliJ IDEA cannot drop component onto form

I'm very new to IDEA, and I wonder why my Custom Component can't be added to the GUI. I created a new project and added a new GUI and a new class which is a Component.
Here's the code for the Component:
package comps;
import javax.swing.*;
/**
* Created by danielmartin1 on 25.03.15.
*/
public class TestComp extends JLabel {
}
I'm using OSX Yosemite, with the JDK 1.8
Hope anyone can help me.
Using the custom bundled IDEA helped. Now i can add any Custom Component the GUI.
But there are now some other problems:
First, the component doesn't look as it should in the form editor (it looks like a combobox),
and Second: My program crashes when trying to run if the layout is set to GridlayoutManager(IntelliJ). With Borderlayout selected, it is running and my component is shown (only at runtime) correctly.
So here is the code for my component:
package gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class CustomTracker extends JComponent implements MouseListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private boolean isSelected = false;
public String getText() {
return text;
}
public String text;
public int fontSize = 13;
private ImageIcon iIBack = new ImageIcon(getClass().getResource("/CheckBox/Tracker_Back.png"));
private ImageIcon iIButton = new ImageIcon(getClass().getResource("/CheckBox/Tracker_Button.png"));
private ImageIcon stretchedBack, stretchedButton;
private Font fontTracker = new Font("Arial", Font.BOLD, fontSize);
private Font fontText = new Font("Arial", Font.BOLD, fontSize);
private Color textColor = new Color(103, 125, 129);
private Color buttonColor = new Color(255, 255, 255);
private int backOriginalWidth, backOriginalHeight;
private int buttonOriginalWidth, buttonOriginalHeight;
private float scale = .7f;
/**
* Constructor
*
* #param text
* set the text of this component
*/
public CustomTracker(String text) {
this.text = text;
this.setSize(this.getWidth(), iIBack.getIconHeight());
this.addMouseListener(this);
this.backOriginalWidth = iIBack.getIconWidth();
this.backOriginalHeight = iIBack.getIconHeight();
this.buttonOriginalWidth = iIButton.getIconWidth();
this.buttonOriginalHeight = iIButton.getIconHeight();
// Stretch Back
Image img = iIBack.getImage();
Image newimg = img.getScaledInstance((int) (backOriginalWidth * scale), (int) (backOriginalHeight * scale), java.awt.Image.SCALE_SMOOTH);
stretchedBack = new ImageIcon(newimg);
// Stretch Button
img = iIButton.getImage();
newimg = img.getScaledInstance((int) (buttonOriginalWidth * scale), (int) (buttonOriginalHeight * scale), java.awt.Image.SCALE_SMOOTH);
stretchedButton = new ImageIcon(newimg);
// stretch font
this.fontSize = (int)(this.fontSize * scale);
this.fontTracker = new Font("Arial", Font.BOLD, fontSize);
}
/**
* get selected value
*/
// #Override
// public boolean isSelected() {
// return this.isSelected;
// }
/**
* set selected value
*
* #param selected
* the value
*/
public void setSelected(boolean selected) {
this.isSelected = selected;
}
#Override
public Dimension getMinimumSize() {
return new Dimension(this.getWidth(), this.getHeight());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(this.getWidth(), this.getHeight());
}
/**
* paint the component
*
* #param g
* the graphics object
*/
protected void paintComponent(Graphics g) {
// create a Graphics2D Object
Graphics2D g2d = (Graphics2D) g.create();
// Draw Box Image
g2d.drawImage(stretchedBack.getImage(), 0, 0, stretchedBack.getIconWidth(), stretchedBack.getIconHeight(), this);
// Set Font-Values
g2d.setFont(fontTracker);
g2d.setColor(buttonColor);
// Set text coordinates
int x;
int y = (int) (((iIBack.getIconHeight() / 2) + (fontSize / 2) + 1) * scale);
if (this.isSelected == true) {
g2d.drawImage(stretchedButton.getImage(), (int) (40 * scale), (int) (2 * scale), stretchedButton.getIconWidth(),
stretchedButton.getIconHeight(), this);
x = (int) (15 * scale);
g2d.drawString("ON", x, y);
} else {
g2d.drawImage(stretchedButton.getImage(), 0, (int) (2 * scale), stretchedButton.getIconWidth(), stretchedButton.getIconHeight(), this);
x = (int) (37 * scale);
g2d.drawString("OFF", x, y);
}
// Draw ON or OFF
g2d.drawString(getText(), (int)((iIBack.getIconWidth() + 10) * scale), y);
// Set Font-Values
g2d.setFont(fontText);
g2d.setColor(textColor);
// Set new y-Position
y = ((stretchedBack.getIconHeight() / 2) + (fontSize / 2) + 1);
// draw the text behind the Control
g2d.drawString(getText(), stretchedBack.getIconWidth() + 10, y);
// dispose Variables
g2d.dispose();
}
#Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
}
/**
* set the text of this component
*
* #param text
* the text to display
*/
public void setText(String text) {
setText(text);
}
public void mouseClicked(MouseEvent e) {
this.isSelected = !this.isSelected;
repaint();
}
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
Does anyone know a solution for these problems?

Why is the class CanvasPane not included in the Java API?

** Why is the class CanvasPane not included in the Java API?.
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
/**
* Class Canvas - a class to allow for simple graphical
* drawing on a canvas.
*
* #author Michael Kolling (mik)
* #author Bruce Quig
*
* #version 2008.03.30
*/
public class Canvas
{
private JFrame frame;
private CanvasPane canvas;
private Graphics2D graphic;
private Color backgroundColor;
private Image canvasImage;
/**
* Create a Canvas with default height, width and background color
* (300, 300, white)
* #param title title to appear in Canvas Frame
*/
public Canvas(String title)
{
this(title, 300, 300, Color.white);
}
/**
* Create a Canvas with default background color (white).
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
*/
public Canvas(String title, int width, int height)
{
this(title, width, height, Color.white);
}
/**
* Create a Canvas.
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
* #param bgClour the desired background color of the canvas
*/
public Canvas(String title, int width, int height, Color bgColor)
{
frame = new JFrame();
canvas = new CanvasPane();
frame.setContentPane(canvas);
frame.setTitle(title);
canvas.setPreferredSize(new Dimension(width, height));
backgroundColor = bgColor;
frame.pack();
}
/**
* Set the canvas visibility and brings canvas to the front of screen
* when made visible. This method can also be used to bring an already
* visible canvas to the front of other windows.
* #param visible boolean value representing the desired visibility of
* the canvas (true or false)
*/
public void setVisible(boolean visible)
{
if(graphic == null) {
// first time: instantiate the offscreen image and fill it with
// the background color
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColor);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(true);
}
/**
* Provide information on visibility of the Canvas.
* #return true if canvas is visible, false otherwise
*/
public boolean isVisible()
{
return frame.isVisible();
}
/**
* Draw the outline of a given shape onto the canvas.
* #param shape the shape object to be drawn on the canvas
*/
public void draw(Shape shape)
{
graphic.draw(shape);
canvas.repaint();
}
/**
* Fill the internal dimensions of a given shape with the current
* foreground color of the canvas.
* #param shape the shape object to be filled
*/
public void fill(Shape shape)
{
graphic.fill(shape);
canvas.repaint();
}
/**
* Fill the internal dimensions of the given circle with the current
* foreground color of the canvas.
*/
public void fillCircle(int xPos, int yPos, int diameter)
{
Ellipse2D.Double circle = new Ellipse2D.Double(xPos, yPos, diameter, diameter);
fill(circle);
}
/**
* Fill the internal dimensions of the given rectangle with the current
* foreground color of the canvas. This is a convenience method. A similar
* effect can be achieved with the "fill" method.
*/
public void fillRectangle(int xPos, int yPos, int width, int height)
{
fill(new Rectangle(xPos, yPos, width, height));
}
/**
* Erase the whole canvas.
*/
public void erase()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
canvas.repaint();
}
/**
* Erase the internal dimensions of the given circle. This is a
* convenience method. A similar effect can be achieved with
* the "erase" method.
*/
public void eraseCircle(int xPos, int yPos, int diameter)
{
Ellipse2D.Double circle = new Ellipse2D.Double(xPos, yPos, diameter, diameter);
erase(circle);
}
/**
* Erase the internal dimensions of the given rectangle. This is a
* convenience method. A similar effect can be achieved with
* the "erase" method.
*/
public void eraseRectangle(int xPos, int yPos, int width, int height)
{
erase(new Rectangle(xPos, yPos, width, height));
}
/**
* Erase a given shape's interior on the screen.
* #param shape the shape object to be erased
*/
public void erase(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.fill(shape); // erase by filling background color
graphic.setColor(original);
canvas.repaint();
}
/**
* Erases a given shape's outline on the screen.
* #param shape the shape object to be erased
*/
public void eraseOutline(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.draw(shape); // erase by drawing background color
graphic.setColor(original);
canvas.repaint();
}
/**
* Draws an image onto the canvas.
* #param image the Image object to be displayed
* #param x x co-ordinate for Image placement
* #param y y co-ordinate for Image placement
* #return returns boolean value representing whether the image was
* completely loaded
*/
public boolean drawImage(Image image, int x, int y)
{
boolean result = graphic.drawImage(image, x, y, null);
canvas.repaint();
return result;
}
/**
* Draws a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void drawString(String text, int x, int y)
{
graphic.drawString(text, x, y);
canvas.repaint();
}
/**
* Erases a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void eraseString(String text, int x, int y)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.drawString(text, x, y);
graphic.setColor(original);
canvas.repaint();
}
/**
* Draws a line on the Canvas.
* #param x1 x co-ordinate of start of line
* #param y1 y co-ordinate of start of line
* #param x2 x co-ordinate of end of line
* #param y2 y co-ordinate of end of line
*/
public void drawLine(int x1, int y1, int x2, int y2)
{
graphic.drawLine(x1, y1, x2, y2);
canvas.repaint();
}
/**
* Sets the foreground color of the Canvas.
* #param newColor the new color for the foreground of the Canvas
*/
public void setForegroundColor(Color newColor)
{
graphic.setColor(newColor);
}
/**
* Returns the current color of the foreground.
* #return the color of the foreground of the Canvas
*/
public Color getForegroundColor()
{
return graphic.getColor();
}
/**
* Sets the background color of the Canvas.
* #param newColor the new color for the background of the Canvas
*/
public void setBackgroundColor(Color newColor)
{
backgroundColor = newColor;
graphic.setBackground(newColor);
}
/**
* Returns the current color of the background
* #return the color of the background of the Canvas
*/
public Color getBackgroundColor()
{
return backgroundColor;
}
/**
* changes the current Font used on the Canvas
* #param newFont new font to be used for String output
*/
public void setFont(Font newFont)
{
graphic.setFont(newFont);
}
/**
* Returns the current font of the canvas.
* #return the font currently in use
**/
public Font getFont()
{
return graphic.getFont();
}
/**
* Sets the size of the canvas.
* #param width new width
* #param height new height
*/
public void setSize(int width, int height)
{
canvas.setPreferredSize(new Dimension(width, height));
Image oldImage = canvasImage;
canvasImage = canvas.createImage(width, height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.drawImage(oldImage, 0, 0, null);
frame.pack();
}
/**
* Returns the size of the canvas.
* #return The current dimension of the canvas
*/
public Dimension getSize()
{
return canvas.getSize();
}
/**
* Waits for a specified number of milliseconds before finishing.
* This provides an easy way to specify a small delay which can be
* used when producing animations.
* #param milliseconds the number
*/
public void wait(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (InterruptedException e)
{
// ignoring exception at the moment
}
}
/************************************************************************
* Inner class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
}
Why it should be? I mean its a BlueJ extension class, AFAIK. Similar questions may come to the mind regarding StringUtils, or NumberUtils. IMHO, these two really qualifies to be there in the original Java API. :)
One huge reason is that it has one of the worst named methods I have ever seen in a Java class:
public void wait(int milliseconds)
Try calling wait(100) on it and watch it work without synchronisation and obviously do something completely different from java.lang.Object.wait(long). This would be a nightmare to do in production.
What on earth is such a method doing in a class named Canvas?

Categories