In my application, there are things marked on an image by clicking on the image. That is done by setting the image as an Icon to a JLabel and adding a MousePressed method
I want to add a feature for the users to redo the last step now and need a backupimage for that.
The following is a code example:
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class BuffImgTest {
private BufferedImage buffimg, scaledimg, backupscaledimg;
private Image img;
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
BuffImgTest window = new BuffImgTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public BuffImgTest() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
final JLabel label = new JLabel("");
label.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent arg0) {
Graphics graphics = scaledimg.getGraphics();
graphics.setColor(Color.RED);
graphics.drawString("Test", arg0.getX(), arg0.getY());
Image img = Toolkit.getDefaultToolkit().createImage(
scaledimg.getSource());
label.setIcon(new ImageIcon(img));
}
});
label.setBounds(10, 34, 414, 201);
try {
buffimg = ImageIO.read(new File("test.jpg"));
scaledimg = getScaledImage(buffimg, label.getWidth(),
label.getHeight());
backupscaledimg = scaledimg;
// backupscaledimg=getScaledImage(buffimg,label.getWidth(),label.getHeight());
Image img = Toolkit.getDefaultToolkit().createImage(
scaledimg.getSource());
label.setIcon(new ImageIcon(img));
} catch (Exception e) {
System.out.println(e);
}
frame.getContentPane().add(label);
JButton btnNewButton = new JButton("Restart Step");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
scaledimg = backupscaledimg;
Image img = Toolkit.getDefaultToolkit().createImage(
scaledimg.getSource());
label.setIcon(new ImageIcon(img));
}
});
btnNewButton.setBounds(111, 238, 89, 23);
frame.getContentPane().add(btnNewButton);
}
public static BufferedImage getScaledImage(BufferedImage image, int width,
int height) throws IOException {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
double scaleX = (double) width / imageWidth;
double scaleY = (double) height / imageHeight;
AffineTransform scaleTransform = AffineTransform.getScaleInstance(
scaleX, scaleY);
AffineTransformOp bilinearScaleOp = new AffineTransformOp(
scaleTransform, AffineTransformOp.TYPE_BILINEAR);
return bilinearScaleOp.filter(image, new BufferedImage(width, height,
image.getType()));
}
}
It is not working as intended.
If I use the commented line backupscaledimg = getScaledImage(buffimg,label.getWidth(),label.getHeight()); instead of backupscaledimg = scaledimg;, it is working as expected.
The problem is that I want to do several steps of drawing things on the image, and it can only be redone the first time like that. From what I know the problem might be, that the command backupscaledimg = scaledimg is only creating a pointer for backupscaledimg pointing to scaledimg which results in both of them altering.
I don't want to save a new imagefile on each step though.
Is there any way around this? (found the scaling function on here by the way thanks for that anonymous)
Made some changes
Using GridBagLayout
Able to reset back to original image by pressing "Restart Step"
Able to undo last action with the use of an image stack (i.e. a Stack of BufferedImage)
Example code:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Stack;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class BuffImgTest {
private BufferedImage scaledImg, originalScaledImg;
private JFrame frame;
private Stack<BufferedImage> imageStack = new Stack<>();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
BuffImgTest window = new BuffImgTest();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public BuffImgTest() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
JPanel panel = new JPanel(new GridBagLayout());
final JLabel imgLabel = new JLabel("");
imgLabel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent arg0) {
// Add current image to the image stack
imageStack.add(copyImage(scaledImg));
// Change the image
Graphics graphics = scaledImg.getGraphics();
graphics.setColor(Color.BLACK);
graphics.setFont(new Font("Arial", Font.BOLD, 32));
graphics.drawString("TEST", arg0.getX(), arg0.getY());
// Update label
Image img = Toolkit.getDefaultToolkit().createImage(
scaledImg.getSource());
imgLabel.setIcon(new ImageIcon(img));
}
});
imgLabel.setSize(500, 500);
imgLabel.setPreferredSize(new Dimension(500, 500));
try {
BufferedImage buffImg = ImageIO.read(new File("test.jpg"));
scaledImg = getScaledImage(buffImg, imgLabel.getWidth(),
imgLabel.getHeight());
// Clone it first
originalScaledImg = copyImage(scaledImg);
Image img = Toolkit.getDefaultToolkit().createImage(
scaledImg.getSource());
imgLabel.setIcon(new ImageIcon(img));
} catch (Exception e) {
System.out.println(e);
}
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(20, 10, 10, 10);
panel.add(imgLabel, c);
JButton restartBtn = new JButton("Restart Step");
restartBtn.setFont(new Font("Arial", Font.ITALIC, 20));
restartBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// Clear the image stack
imageStack.clear();
// Reset the image
scaledImg = copyImage(originalScaledImg);
Image img = Toolkit.getDefaultToolkit().createImage(
scaledImg.getSource());
imgLabel.setIcon(new ImageIcon(img));
}
});
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 1;
c.anchor = GridBagConstraints.CENTER;
c.insets = new Insets(10, 10, 5, 10);
panel.add(restartBtn, c);
JButton undoBtn = new JButton("Undo Last");
undoBtn.setFont(new Font("Arial", Font.ITALIC, 20));
undoBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if(imageStack.isEmpty()) {
JOptionPane.showMessageDialog(frame, "Cannot undo anymore!");
return;
}
// Get the previous image
scaledImg = copyImage(imageStack.pop());
Image img = Toolkit.getDefaultToolkit().createImage(
scaledImg.getSource());
imgLabel.setIcon(new ImageIcon(img));
}
});
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 2;
c.anchor = GridBagConstraints.CENTER;
c.insets = new Insets(5, 10, 20, 10);
panel.add(undoBtn, c);
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setSize(800, 800);
}
/** For copying image */
public static BufferedImage copyImage(BufferedImage source){
BufferedImage b = new BufferedImage(
source.getWidth(), source.getHeight(), source.getType());
Graphics g = b.getGraphics();
g.drawImage(source, 0, 0, null);
g.dispose();
return b;
}
public static BufferedImage getScaledImage(BufferedImage image, int width,
int height) throws IOException {
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
double scaleX = (double) width / imageWidth;
double scaleY = (double) height / imageHeight;
AffineTransform scaleTransform = AffineTransform.getScaleInstance(
scaleX, scaleY);
AffineTransformOp bilinearScaleOp = new AffineTransformOp(
scaleTransform, AffineTransformOp.TYPE_BILINEAR);
return bilinearScaleOp.filter(image, new BufferedImage(width, height,
image.getType()));
}
}
Edited Image:
Image after pressing "Restart step":
Pressing "Undo Last" when image stack is empty:
Note:
Code for copying image is from this answer by APerson
Related
How to draw something over all components of a Panel?
In the code below I tried to do this overriding the paintComponent method, I call super.paintComponent(g) hoping this will draw all components added as part of the constructor, but still my X stays below the image.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Stack extends JPanel {
private final JLabel some_text = new JLabel("Some very long text that will be covered", JLabel.LEFT);
private final JLabel some_icon = new JLabel((Icon)null, JLabel.CENTER);
public static final String COMPASS_URL = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Compass_Rose_English_North.svg/240px-Compass_Rose_English_North.svg.png";
public Stack() throws IOException {
super(new GridBagLayout());
URL compassUrl = new URL(COMPASS_URL);
BufferedImage compassImage = ImageIO.read(compassUrl);
ImageIcon compassIcon = new ImageIcon(compassImage);
some_icon.setIcon(compassIcon);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
add(some_icon, c);
c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;
add(some_text, c);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(15));
g2.drawLine(0, 0, this.getWidth(), this.getHeight());
g2.drawLine(this.getWidth(), 0, 0, this.getHeight());
g2.dispose();
}
private static void createAndShowUI() throws IOException {
JFrame frame = new JFrame("MyFrame");
frame.getContentPane().add(new Stack());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
createAndShowUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
Is there a way to bring my X to the foreground or to wait for super.paintComponent(g) to paint everything, and then run the code that draws the X?
Thanks,
Roberto
Override the paint(…) method of your JPanel:
protected void paint(Graphics g)
{
super.paint(g);
// add custom painting code here
}
The paint(…) method invokes the paintChildren(…) method so your custom code will be executed after all the components on the panel are painted.
See A Closer Look at the Painting Mechanism for more information.
Try this. I made the following changes.
Drew the image in paintComponent as opposed to setIcon.
positioned the image to center it.
used setPreferredSize for real panel size (setting frame size includes borders which is probably not what you wanted).
used RenderingHints in paintComponent to smooth out edges of cross.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Stack2 extends JPanel {
private final JLabel some_text = new JLabel(
"Some very long text that will be covered", JLabel.LEFT);
private final JLabel some_icon =
new JLabel((Icon) null, JLabel.CENTER);
public static final String COMPASS_URL =
"https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Compass_Rose_English_North.svg/240px-Compass_Rose_English_North.svg.png";
BufferedImage compassImage;
public Stack2() throws IOException {
super(new GridBagLayout());
URL compassUrl = new URL(COMPASS_URL);
compassImage = ImageIO.read(compassUrl);
// ImageIcon compassIcon = new ImageIcon(compassImage);
// some_icon.setIcon(compassIcon);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
add(some_icon, c);
c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 1;
add(some_text, c);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawImage(compassImage,
(400 - compassImage.getWidth()) / 2,
(400 - compassImage.getHeight()) / 2, null);
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(15));
g2.drawLine(0, 0, this.getWidth(), this.getHeight());
g2.drawLine(this.getWidth(), 0, 0, this.getHeight());
g2.dispose();
}
private static void createAndShowUI() throws IOException {
JFrame frame = new JFrame("MyFrame");
Stack2 panel = new Stack2();
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.setPreferredSize(new Dimension(400, 400));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
createAndShowUI();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
Downloaded some code to display Splash Screen from O'Reilly, but When I do some modified some text to display as per need.
I did some investigation, and debug the program but found nothing.
Is that any windows platform issue?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
public class SplashScreen extends JWindow {
private int duration;
byte[] msg = new byte[]{65,112,114,105,108,32,70, 111, 111,108};
String text = "";
public SplashScreen(int d) {
duration = d;
}
// A simple little method to show a title screen in the center
// of the screen for the amount of time given in the constructor
public void showSplash() throws Exception {
JPanel content = (JPanel)getContentPane();
content.setBackground(Color.white);
// Set the window's bounds, centering the window
int width = 450;
int height =300;
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
int x = (screen.width-width)/2;
int y = (screen.height-height)/2;
setBounds(x,y,width,height);
JLabel txt = new JLabel
(new String(msg), JLabel.CENTER);
txt.setFont(new Font("Sans-Serif", Font.BOLD, 32));
// Build the splash screen
JLabel label = new JLabel(new ImageIcon("oreilly.gif"));
JLabel copyrt = new JLabel
(new String(msg), JLabel.CENTER);
URL url = new URL("http://findicons.com/files/icons/360/emoticons/128/satisfied.png");
BufferedImage img = ImageIO.read(url);
ImageIcon icon = new ImageIcon(img);
JLabel iconL = new JLabel(icon);
copyrt.setFont(new Font("Sans-Serif", Font.BOLD, 12));
content.add(label, BorderLayout.CENTER);
content.add(txt, BorderLayout.CENTER);
content.add(iconL, BorderLayout.CENTER);
content.add(copyrt, BorderLayout.SOUTH);
Color oraRed = new Color(156, 20, 20, 255);
content.setBorder(BorderFactory.createLineBorder(oraRed, 10));
// Display it
setVisible(true);
// Wait a little while, maybe while loading resources
try { Thread.sleep(duration); } catch (Exception e) {}
setVisible(false);
}
public void showSplashAndExit() {
try {
showSplash();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.exit(0);
}
public static void main(String[] args) {
// Throw a nice little title page up on the screen first
SplashScreen splash = new SplashScreen(10000);
// Normally, we'd call splash.showSplash() and get on with the program.
// But, since this is only a test...
splash.showSplashAndExit();
}
}
I got a problem, what I want to do is basically create a panel where I can Translate, Scale, Rotate and Reflex a Rectangle by giving some info on textbox and click a button, I already drawn a rectangle and I can move it before drawing it, but I need to transform it after drawn and what I want is to only transform the rectangle and not the guide lines, how can I do this? this is my code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Ventana extends JFrame implements ActionListener {
MiPanel panelFigura = new MiPanel();
JPanel panelBotones = new JPanel();
JButton btnTransladar = new JButton("Translador"); // Means translate
JButton btnEscala = new JButton("Escala"); // Means Scale
JButton btnRotar = new JButton("Rotar"); // Means Rotate
JTextField txT = new JTextField(4);
JTextField tyT = new JTextField(4);
JTextField exT = new JTextField(4);
JTextField eyT = new JTextField(4);
JTextField gradoT = new JTextField(3);
public Ventana() {
setSize(800, 600);
setVisible(true);
setTitle("Unidad 2");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
add(panelFigura);
panelBotones.add(new JLabel("x: "));
panelBotones.add(txT);
panelBotones.add(new JLabel("y: "));
panelBotones.add(tyT);
btnTransladar.addActionListener(this);
panelBotones.add(btnTransladar);
panelBotones.add(new JLabel("x: "));
panelBotones.add(exT);
panelBotones.add(new JLabel("y: "));
panelBotones.add(eyT);
panelBotones.add(btnEscala);
panelBotones.add(new JLabel("º: "));
panelBotones.add(gradoT);
panelBotones.add(btnRotar);
panelBotones.setBackground(Color.LIGHT_GRAY);
btnRotar.addActionListener(this);
btnTransladar.addActionListener(this);
btnEscala.addActionListener(this);
add(panelBotones, BorderLayout.SOUTH);
}
public class MiPanel extends JPanel {
public int tx = 0, ty = 0, ex = 0, ey = 0, grado = 0; // tx and ty are
// how many
// pixel is the
// rectangle
// moving, ex
// and ex is how
// much is
// scaling and
// grado is the
// angle of the
// rotation
Rectangle2D.Double rectangulo = new Rectangle2D.Double(tx, ty, 60, 60);
public MiPanel() {
this.setSize(800, 400);
this.setBackground(Color.WHITE);
}
public void paintComponent(Graphics g) {
// super.paintComponent( g );
Graphics2D g2D = (Graphics2D) g;
g2D.translate((this.getWidth() / 2), (this.getHeight() / 2));
g2D.drawLine((0 - (this.getWidth() / 2)), 0, (this.getWidth() / 2),
0);
g2D.drawLine(0, this.getHeight(), 0, (0 - this.getHeight() / 2));
g2D.draw(rectangulo);
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnTransladar) {
panelFigura.tx = Integer.getInteger(txT.getText());
panelFigura.ty = Integer.getInteger(tyT.getText());
}
if (e.getSource() == btnEscala) {
panelFigura.ex = Integer.getInteger(exT.getText());
panelFigura.ey = Integer.getInteger(eyT.getText());
}
if (e.getSource() == btnRotar) {
panelFigura.grado = Integer.getInteger(gradoT.getText());
}
}
}
Thanks for helping me out!
I've written this small program which attempts to create a custom JButton unfortunately I can't manage to remove the border. I thought button.setBorder(null); would remove it but this has been ineffective. Does anyone know how to remove the border from the button so it's just the icon? Any help greatly appreciated.
My code is as follows:
package custombuttons;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CustomButtons {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
CustomButtons h = new CustomButtons();
h.setUp();
}
JFrame frame;
JPanel panel;
JButton button;
BufferedImage b;
String toolTip = "Configure";
public void setUp() {
frame = new JFrame("Custom Buttons");
try {
b = ImageIO.read(CustomButtons.class.getResource("/images/config.png"));
} catch (IOException ex) {
Logger.getLogger(CustomButtons.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
Image b1 = (Image) b;
ImageIcon iconRollover = new ImageIcon(b1);
int w = iconRollover.getIconWidth();
int h = iconRollover.getIconHeight();
GraphicsConfiguration gc = frame.getGraphicsConfiguration();
Image image = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
Graphics2D g = (Graphics2D) image.getGraphics();
g.drawImage(iconRollover.getImage(), 0, 0, null);
g.dispose();
ImageIcon iconDefault = new ImageIcon(b1);
image = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
g = (Graphics2D) image.getGraphics();
g.drawImage(iconRollover.getImage(), 2, 2, null);
g.dispose();
ImageIcon iconPressed = new ImageIcon(b1);
JButton button = new JButton();
button.setIgnoreRepaint(true);
button.setFocusable(false);
button.setToolTipText(toolTip);
button.setBorder(null);
button.setContentAreaFilled(false);
button.setIcon(iconDefault);
button.setRolloverIcon(iconRollover);
button.setPressedIcon(iconPressed);
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
panel = new JPanel();
panel.setOpaque(false);
panel.add(button);
frame.getContentPane().add(panel);
frame.setVisible(true);
}
}
have look at button.setBorderPainted(false) more about JButton here
actually i tested your code on my Netbeans IDE and got no borders as you desire
using only button.setBorder(null); or button.setBorderPainted(false); or both of them but
i think you should make sure that your original image is really do not have any borders it self
I submitted another version of this question and a sample program before: How do I get consistent rendering when scaling a JTextPane?
Recapitulating the problem: I would like to allow users to zoom into or out of a non-editable JTextPane. Running the example program submitted in the earlier question, which simply scaled the Graphics object, resulted in inconsistent spacing between runs of bold text and non-bold text.
The sample program below attempts to solve the problem by drawing the text pane to a BufferedImage at 100% and then scaling the image. This solves the problem of inconsistent spacing but the resulting text lacks crispness. Is there some combination of rendering hints (or some other change) that will result in nice crisp text?
Thanks in advance for any suggestions or comments on the feasibility of this approach.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.Box;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
public class ScaledJTextPane extends JTextPane
{
double scale_;
BufferedImage raster_;
public ScaledJTextPane()
{
scale_ = 1.0;
raster_ = null;
}
public void draw(Graphics g)
{
if (raster_ == null)
{
// Draw this text pane to a BufferedImage at 100%
raster_ = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = raster_.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
paint(g2);
}
Graphics2D g2 = (Graphics2D) g;
// Experiment with different rendering hints
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
// Scale the BufferedImage
g2.scale(scale_, scale_);
g2.drawImage(raster_, 0, 0, null);
}
public void setScale(double scale)
{
scale_ = scale;
raster_ = null;
}
private static void createAndShowGUI()
{
// Create and set up the window.
JFrame frame = new JFrame("ScaledJTextPane using BufferedImage");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ScaledJTextPane scaledTextPane = new ScaledJTextPane();
StyledDocument doc = scaledTextPane.getStyledDocument();
Style defaultStyle = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
Style boldStyle = doc.addStyle("bold", defaultStyle);
StyleConstants.setBold(boldStyle, true);
scaledTextPane.setFont(new Font("Dialog", Font.PLAIN, 14));
String boldText = "Four score and seven years ago ";
String plainText = "our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.";
try
{
doc.insertString(doc.getLength(), boldText, boldStyle);
doc.insertString(doc.getLength(), plainText, defaultStyle);
}
catch (BadLocationException ble)
{
System.err.println("Couldn't insert text into text pane.");
}
final JComboBox zoomCombo=new JComboBox(new String[] {"75%",
"100%", "150%", "175%", "200%"});
final JPanel panel = new JPanel()
{
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
scaledTextPane.draw(g);
}
};
zoomCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s = (String) zoomCombo.getSelectedItem();
s = s.substring(0, s.length() - 1);
double scale = new Double(s).doubleValue() / 100;
scaledTextPane.setScale(scale);
panel.invalidate();
panel.repaint();
}
});
zoomCombo.setSelectedItem("100%");
JPanel optionsPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.WEST;
optionsPanel.add(zoomCombo, c);
c.gridx++;
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
optionsPanel.add(Box.createHorizontalGlue(), c);
// Add content to the window.
scaledTextPane.setBounds(0, 0, 450, 300);
panel.setOpaque(true);
panel.setBackground(Color.WHITE);
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.getContentPane().add(optionsPanel, BorderLayout.NORTH);
frame.setSize(900, 300);
//Display the window.
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
may be this http://java-sl.com/Scale_In_JEditorPane.html could help.
Sadly, scaling to a larger size from a fixed resolution will always result in some aliasing artifact. Here's an alternative approach that scales the font used by JTextPane.
For low-level control, consider TextLayout, which includes a FontRenderContext that can manage the anti-aliasing and fractional metrics settings, as seen in this example.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
/** #see https://stackoverflow.com/questions/4566211 */
public class ScaledJTextPane {
private static final int SIZE = 14;
private static final String FONT = "Dialog";
private static void createAndShowGUI() {
JFrame frame = new JFrame("ScaledJTextPane using BufferedImage");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JTextPane tp = new JTextPane();
tp.setFont(new Font(FONT, Font.PLAIN, SIZE));
tp.setPreferredSize(new Dimension(400, 300));
StyledDocument doc = tp.getStyledDocument();
Style defaultStyle = StyleContext.getDefaultStyleContext()
.getStyle(StyleContext.DEFAULT_STYLE);
Style boldStyle = doc.addStyle("bold", defaultStyle);
StyleConstants.setBold(boldStyle, true);
String boldText = "Four score and seven years ago ";
String plainText = "our fathers brought forth on this continent, "
+ "a new nation, conceived in Liberty, and dedicated to the "
+ "proposition that all men are created equal.";
try {
doc.insertString(doc.getLength(), boldText, boldStyle);
doc.insertString(doc.getLength(), plainText, defaultStyle);
} catch (BadLocationException ble) {
ble.printStackTrace(System.err);
}
final JPanel panel = new JPanel();
panel.add(tp);
final JComboBox zoomCombo = new JComboBox(new String[]{
"75%", "100%", "150%", "175%", "200%"});
zoomCombo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String s = (String) zoomCombo.getSelectedItem();
s = s.substring(0, s.length() - 1);
double scale = new Double(s).doubleValue() / 100;
int size = (int) (SIZE * scale);
tp.setFont(new Font(FONT, Font.PLAIN, size));
}
});
zoomCombo.setSelectedItem("100%");
JPanel optionsPanel = new JPanel();
optionsPanel.add(zoomCombo);
panel.setBackground(Color.WHITE);
frame.add(panel, BorderLayout.CENTER);
frame.add(optionsPanel, BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
}
I would like to allow users to zoom into or out of a non-editable JTextPane.
Since the text pane is non-editable, maybe you can create an image of the text pane by using the Screen Image class. Then you can draw the image on a panel using the approriate scaling factor.