Graphics2d Stuff - java

Hey i am new to this whole coding scene and i was wondering if there was a way to this:
Graphics2D g = bufferedImage.getGraphics();
In a similar fashion to how you would do this:
int j = Integer.parseint(JOptionPane.showInputDialog);
Here is all of my code(Sorry i know its messy):
public class Drawing extends Canvas {
public static void main (String[]args) {
JFrame frame = new JFrame();
frame.setSize(800, 400);//height in pixles
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//closed program
Canvas canvas = new Drawing();
canvas.setBackground(Color.black);
canvas.setSize(800, 400);
frame.add(canvas);
frame.pack();
frame.setVisible(true);
}
private Image createImageWithText() {
BufferedImage bufferedImage = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
Graphics2D g = bufferedImage.getGraphics();
Image greenskull = Toolkit.getDefaultToolkit().getImage("C:\\Users\\Powell Design\\Pictures\\Saved Pictures\\greenskull");
//gets image from c drive
g.drawImage(greenskull);
return bufferedImage;
}
}

Related

JComponent for images with no zoom for HiDPI

I'd like to have a component that shows an image in Java without zooming on HiDPI screens.
The obvious candidate is to use a JLabel. I've succesfully done it by overwriting the AffineTransform in paintComponent but it remains the problem that the label preferred size is incorrect on HiDPI.
The following example seems to work even when I move the window from HiDPI (4K scaled 1.75) to FullHD (scale 1.0) except for the size of the component on HiDPI which is larger than the image displayed.
How can I achieve to have the preferred size of a component not to be zoomed on a HiDPI screen?
public class UnscaledImage extends JPanel {
private AffineTransform noChangeTransform = new AffineTransform();
private JLabel imageLabel;
private JLabel colorLabel = new JLabel("Color");
private BufferedImage image;
private double scale = 1.0;
public UnscaledImage() {
initUI();
packAndShow("Unscaled Image");
}
public void initUI() {
setLayout(new BorderLayout());
ImageIcon imageIcon = (ImageIcon) UIManager.getIcon("OptionPane.warningIcon");
image = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = image.createGraphics();
g2d.drawImage(imageIcon.getImage(), 0, 0, null);
g2d.dispose();
imageLabel = new JLabel() {
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
AffineTransform oldTransform = g2d.getTransform();
scale = oldTransform.getScaleX();
Dimension labelPrefSize = imageLabel.getPreferredSize();
if (scale != 1.0 && labelPrefSize.width == image.getWidth()) {
imageLabel.setSize(new Dimension((int) (labelPrefSize.width / scale), (int) (labelPrefSize.height / scale)));
SwingUtilities.windowForComponent(imageLabel).pack();
}
g2d.setTransform(noChangeTransform);
super.paintComponent(g);
g2d.setTransform(oldTransform);
}
};
imageLabel.setIcon(imageIcon);
imageLabel.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseMoved(MouseEvent me) {
int mouseX = (int) (me.getX() * scale);
int mouseY = (int) (me.getY() * scale);
if (mouseX < image.getWidth() && mouseY < image.getHeight()) {
int color = image.getRGB(mouseX, mouseY);
colorLabel.setBackground(new Color(color));
}
}
});
colorLabel.setOpaque(true);
colorLabel.setBackground(Color.WHITE);
add(imageLabel, BorderLayout.CENTER);
add(colorLabel, BorderLayout.SOUTH);
}
public void packAndShow(String title) {
JFrame frame = new JFrame(title);
frame.add(this);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public final static void main(String[] args) {
SwingUtilities.invokeLater(() -> new UnscaledImage());
}
}

How to make holes in a shape in Piccolo2D?

In main Java it supports "winding rule" which may help to make holes in the shapes.
Unfortunately, this concept is ignored in Piccolo2D:
public class Try_Holes_01 {
#SuppressWarnings("serial")
public static void main(String[] args) {
final Path2D path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
//final Path2D path = new Path2D.Double(Path2D.WIND_NON_ZERO);
path.append(new Ellipse2D.Double(100,100,200,200), false);
path.append(new Ellipse2D.Double(120,120,100,100), false);
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(path);
}
};
final PPath path_p = new PPath(path);
path_p.setPaint(Color.BLACK);
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(panel, BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
new PFrame() {
#Override
public void initialize() {
getCanvas().getLayer().addChild(path_p);
}
};
}
}
So how to make holes inside Piccolo2D paths?
PPath maintains a private GeneralPath member for its operations. It is initialized with WIND_NON_ZERO. Luckily it can be accessed with PPath.getPathReference(). So this should do the trick:
path_p.getPathReference().setWindingRule(Path2D.WIND_EVEN_ODD);
Here is a result:

How can I add images as a JPanel background?

I would like to make four panels using different backgrounds, and merge them together using a BorderLayout. I used JLabel, but I can't add any component to a JLabel, therefore I need to make it as a background.
I've search some code but it only tell how to add a background in JFrame.
import javax.swing.*;
import java.awt.*;
public class LoginPanel extends JFrame{
private ImageIcon top = new ImageIcon("C:/Users/user/Desktop/top.png");
private ImageIcon mid = new ImageIcon("C:/Users/user/Desktop/mid.png");
private ImageIcon center = new ImageIcon("C:/Users/user/Desktop/center.png");
private ImageIcon bottom = new ImageIcon("C:/Users/user/Desktop/bottom.png");
public LoginPanel(){
JPanel topp = new JPanel();
topp.setLayout(new BorderLayout(0,0));
topp.add(new JLabel(top),BorderLayout.NORTH);
JPanel centerp = new JPanel();
centerp.setLayout(new BorderLayout(0,0));
centerp.add(new JLabel(mid),BorderLayout.NORTH);
centerp.add(new JLabel(center),BorderLayout.SOUTH);
topp.add(new JLabel(bottom),BorderLayout.SOUTH);
topp.add(centerp,BorderLayout.CENTER);
add(topp);
}
public static void main(String[] args) {
LoginPanel frame = new LoginPanel();
frame.setTitle("Test");
frame.setSize(812, 640);
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
I would make a new class called JImagePanel, and then use that:
class JImagePanel extends JComponent {
private static final long serialVersionUID = 1L;
public BufferedImage image;
public JImagePanel(BufferedImage image)
{
this.image = image;
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// scale image
BufferedImage before = image;
int w = before.getWidth();
int h = before.getHeight();
BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
AffineTransform at = new AffineTransform();
at.scale(2.0, 2.0);
AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
after = scaleOp.filter(before, after);
// center image and draw
Graphics2D g2d = (Graphics2D) g;
int x = (getWidth() - 1 - image.getWidth(this)) / 2;
int y = (getHeight() - 1 - image.getHeight(this)) / 2;
g2d.drawImage(image, x, y, this);
g2d.dispose();
}
}
Check out Custom Painting and 2D Graphics
Check out
Add image to panel not using swings
Java: maintaining aspect ratio of JPanel background image
Java background JFrame with a Jpanel arranging images in a grid

I'd like to draw pixels on a window with mouse input

I've done days of searching for a way to draw pixels to a window in java with mouse capture. I'm looking for some framework I can just plug in. It seems like it would be so simple... Any help will be greatly appreciated.
(EDIT)
Here is some non-working code.
public class Base extends JPanel implements MouseMotionListener {
public static void main(String[] args) {
new Base();
}
final static int width = 800;
final static int height = 600;
BufferedImage img;
Base() {
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
JFrame frame = new JFrame();
frame.addMouseMotionListener(this);
frame.add(this);
frame.setSize(width, height);
frame.setEnabled(true);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
Graphics g = img.getGraphics();
g.drawRect(1, 1, width - 2, height - 2);
g.dispose();
repaint();
}
#Override
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}
See comments in the code.
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class Base extends JPanel implements MouseMotionListener {
public static void main(String[] args) {
new Base();
}
final static int width = 400;
final static int height = 300;
BufferedImage img;
Base() {
img = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB_PRE);
// do in preference to setting the frame size..
setPreferredSize(new Dimension(width, height));
JFrame frame = new JFrame();
this.addMouseMotionListener(this); // INSTEAD OF THE FRAME
frame.add(this);
//frame.setSize(width, height); DO INSTEAD...
frame.pack();
//frame.setEnabled(true); REDUNDANT
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // good call!
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
Graphics g = img.getGraphics();
g.setColor(Color.RED); // SET A COLOR
g.drawRect(1, 1, width - 2, height - 2);
// DO SOMETHING UGLY
g.setColor(Color.blue);
Point p = e.getPoint();
g.fillOval(p.x,p.y,5,5);
g.dispose();
repaint();
}
#Override
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}
Use a local BufferedImage on which you want to draw. Add a MouseMotionListener and implement the mouseDragged(MouseMotionEvent evt) method. In that method draw onto the BufferedImage by doing something like this:
// Assume img is your BufferedImage
Graphics g = img.getGraphics();
g.drawRect(evt.getX()-1, evt.getY()-1, 3, 3);
g.dispose();
// repaint your swing component
repaint();
And in your overrided paintComponent(Graphics g) method, draw like this:
g.drawImage(img, 0, 0, null);
Initialize your BufferedImage like this:
img = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
// Assuming `this` is your swing component

What is the simplest way to draw in Java?

What is the simplest way to draw in Java?
import java.awt.*;
import javax.swing.*;
public class Canvas
{
private JFrame frame;
private Graphics2D graphic;
private JPanel canvas;
public Canvas()
{
frame = new JFrame("A title");
canvas = new JPanel();
frame.setContentPane(canvas);
frame.pack();
frame.setVisible(true);
}
public void paint(Graphics g){
BufferedImage offImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Grapics2D g2 = offImg.createGraphics();
g2.setColor(new Color(255,0,0));
g2.fillRect(10,10,200,50);
}
}
This doesn't work and I have no idea how to get anything to appear.
Easiest way:
public class Canvas extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// painting code goes here.
}
}
You simply need to extend JPanel and override the paintComponent method of the panel.
I'd like to reiterate that you should not be overriding the paint method.
Here is a very minimalistic example that works.
public static void main(String[] args) {
JFrame f = new JFrame();
JPanel p = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(0, 0, 100, 100);
}
};
f.add(p);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
// No. 1
// Create a graphics context on the buffered image
Graphics2D g2d = bimage.createGraphics();
// Draw on the buffered image
g2d.setColor(Color.red);
g2d.fill(new Ellipse2D.Float(0, 0, 200, 100));
g2d.dispose();
// No.2
// In case the buffered image supports transparency
g2d = bimage.createGraphics();
// Transparency is created on all the filled pixels
Color transparent = new Color(0, 0, 0, 0);
g2d.setColor(transparent);
g2d.setComposite(AlphaComposite.Src);
g2d.fill(new Rectangle2D.Float(20, 20, 100, 20));
g2d.dispose();
To make something appear in paint(Graphics g) you need to call the drawing methods (like fillRect) on that Graphics. You are creating a bitmap and then drawing to the bitmap, not the screen.
public void paint(Graphics g){
g.setColor(new Color(255,0,0));
g.fillRect(10,10,200,50);
}
jjnguy already wrote how to do it right ... but here why it does not work in your example:
import java.awt.*;
import javax.swing.*;
public class Canvas
Here you have a class which does not relate in any way to Swing or AWT.
(By the way, you may want to select another name to avoid confusion with java.awt.Canvas.)
{
private JFrame frame;
private Graphics2D graphic;
private JPanel canvas;
public Canvas()
{
frame = new JFrame("A title");
canvas = new JPanel();
frame.setContentPane(canvas);
Here you are creating a new JPanel (for confusion also named canvas), and add it to the frame.
Is is this panel's paint and paintComponent methods which are called when the system shows your frame.
frame.pack();
frame.setVisible(true);
}
public void paint(Graphics g){
BufferedImage offImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Grapics2D g2 = offImg.createGraphics();
g2.setColor(new Color(255,0,0));
g2.fillRect(10,10,200,50);
}
This paint method is never used at all (since it is not part of a component), and if it would be called, then you are only painting to some BufferedImage, not to the screen.
}

Categories