I have a loaded image, but when I try to display it nothing is appearing.
public class JComponentButton extends JComponent implements MouseListener {
BufferedImage image;
public static void main(String[] args) {
JFrame mainFrame = new JFrame("Test Title3");
mainFrame.setSize(400,400);
mainFrame.setLayout(new GridLayout(1,1));
mainFrame.addWindowListener(new WindowAdapter() {
#Override public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
JComponentButton button = new JComponentButton();
button.setSize(64,64);
controlPanel.add(button);
mainFrame.add(controlPanel);
mainFrame.setVisible(true);
System.out.println("finishing");
}
public JComponentButton(){
super();
try {
this.image = ImageIO.read(new File("resources/default.png"));
} catch (IOException e) {
System.out.println("did not load image");
System.exit(1);
}
enableInputMethods(true);
addMouseListener(this);
}
#Override public void paintComponent(Graphics g){
super.paintComponent(g);
System.out.println(image.getHeight() + "," + image.getWidth());
g.drawImage(image, 64, 64, null);
}
The image seems to be loaded as 64,64 is printed into the console. However where it should be appearing on the window is blank. I drew a square there without a problem using g.fillRect. So it seems like the problem has to be with g.drawImage. I also tried changing the perspective from null to this, but nothing changed.
In your code the method g.drawImage(image, 64, 64, null) will draw your image at it's full resolution starting at the offset at 64, 64.
Javadoc for drawImage:
Draws as much of the specified image as is currently available. The image is drawn with its top-left corner at (x, y) in this graphics context's coordinate space. Transparent pixels in the image do not affect whatever pixels are already there.
This means that whilst your image is indeed being drawn, it's being drawn outside the visible co-ordinate space of your button.
To fix the issue, replace the 64, 64 with 0, 0 if the image is sized at the component's size or use the more explicit method drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) to specify what the image should be resized to whilst in the button.
E.g.
g.drawImage(image, 0, 0, null); //draws image at full resolution
g.drawImage(image, 0, 0, 64, 64, null); //draws image at offset 0, for max resolution of 64x64
You can't view the image is because the image is drawn outside of the button.
since you don't have any panel outside the button,it cannot be drawn.
The reason is,the x and y axis of the image that you have specified,i.e.Top left corner,are 64,64 and the button is of size 64,64.Thus,this image will be drawn at bottom right of the button,that is the corner point of the button.
Thus you should specify image points as 0,0 (these are the top-left corner of image) so that it will cover the 0,0(these are the top-left corner of button) point of the button.
Also,you must specify the width and height of the image.So,that it will not go out side of bounds of button.If you don't want to specify the width and height then you must decrease the pixels of the image to the size of button(at least).
you can rewrite the code as:
g.drawImage(image,0,0,64,64,null);
Related
I just converted my project from RGB to ARGB. The opaque objects all draw fine but when I add transparency to the 'color' (set by hex: 0x55ff0000) of any drawn object they only draw the correct transparency if they are moving.
The problem: Alpha drawn objects seem to 'stack' up every step until they are opaque.
While they remain stationary they quickly become more and more opaque over a second. I'm still learning how the BufferedImages work but I believe i'm missing a piece of code that I require for ARGB instead of just RGB.
public class Window
{
private JFrame frame;
static BufferedImage image;
private Canvas canvas;
private BufferStrategy bs;
private Graphics g;
public Window(Game game)
{
image = new BufferedImage(game.getWidth(), game.getHeight(), BufferedImage.TYPE_INT_ARGB);
canvas = new Canvas();
Dimension s = new Dimension(game.getWidth() * game.getScale(),game.getHeight() * game.getScale());
canvas.setPreferredSize(s);
canvas.setMaximumSize(s);
canvas.setMinimumSize(s);
frame = new JFrame(game.getName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(canvas, BorderLayout.CENTER); //Add canvas to the frame
frame.pack(); //Set frame to size of canvas
//Removed some other 'frame.xxx' lines of code which don't assist the problem.
//frame.repaint();
canvas.createBufferStrategy(2);
bs = canvas.getBufferStrategy();
g = bs.getDrawGraphics();
}
public void update()
{
g.drawImage(image, 0, 0, canvas.getWidth(), canvas.getHeight(), null); //Draws everything to buffer strategy.
bs.show(); //Draws from buffer strategy to canvas.
}
public JFrame getFrame()
{
return frame;
}
}
The only other code I changed to convert to ARGB was this which was 0 beforehand:
public Renderer(Game game)
{
display = ((DataBufferInt)game.getWindow().getImage().getRaster().getDataBuffer()).getData(); //Displays all the data drawn to screen.
}
public void clear()
{
for(int i = 0; i < display.length; i++) //Loops through the screens pixels and clears them.
{
display[i] = 0xff000000; //Clear the screen with opaque black.
}
}
When I change display[i] = 0xff000000; to 0x0f000000 the problem is exacerbated and it has a slow motion effect - but i'm not sure how to increase an already full alpha of "ff" higher.
I make a GIF of the problem, however it's distorted a fair bit: https://giphy.com/gifs/java-RF6stHznOiR9e
Note how it fades back in after I stop moving, and where the circle overlaps it stays opaque.
in my application I have a cross road picture in the background and I want to draw traffic lights on the top of it (black rectangle with 3 circles)
The problem is, I cannot see the rectangle at all, as if it was under the image or something. And if I switch the order in which the items are painted, I get all black image.
Do you have any idea how this can be solved?I am new to graphics and searched similar questions, but none helped me.
Thank you.
public MainFrame() throws HeadlessException {
super("semafor");
crossroad = new ImageIcon("cross.png");
initFrame();
initComponents();
sem1 = new Semafor(true, 100, 100);
add(sem1);
repaint();
setVisible(true);
}
//here I paint the image
#Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(crossroad.getImage(), 0, 45, this);
}
//and in class Semafor i paint the actual traffic lights
#Override
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.darkGray);
//and then the circles
}
The first thing I'm noticing is that you are calling <unknown>.getWidth() and <unknown>.getHeight() for the rectangle size. If it's covering the entire image, this suggests that it is getting that width and height from the panel it is being drawn on.
A simple stack trace,
(new Exception).printStackTrace();
or
Thread.dumpStack();
will tell you as much. You could also query the width and height with a System.out call to verify that you're getting the values you're expecting, or, if this really gets out of control, learn to use JUnit and the assert statement. Honestly, though, it looks like you're just accidentally calling the wrong method.
I have a JPanel with a size of 816 x 1056 pixels (size of a standard typewriting paper). Is there any way of displaying the whole JPanel and its content without altering its actual size, in a small JFrame? Is there a way of like zooming it out?
I can't think of an easy method to zoom a JPanel out, but you can do it via double-buffering:
private void paintPanel (Graphics2D g)
{
// here goes the code of your paint() or paintComponent() method
}
/** Draw content into an Image, shrink it, and display it. */
protected void paintComponent (Graphics g)
{
// paint image
BufferedImage img = new BufferedImage(MAX_WIDTH, MAX_HEIGHT, BufferedImage.TYPE_INT_ARGB);
paintPanel(img.createGraphics());
// shrink image and paint it
g.drawImage(img, 0,0, WIDTH,HEIGHT, 0,0, MAX_WIDTH,MAX_HEIGHT, null);
}
This will paint everything on a BufferedImage with the size MAX_WIDTH x MAX_HEIGHT. Then, the Image will be shrinked into the size WIDTH x HEIGHT and then displayed.
I am currently doing a project that requires me to draw a large number (100+) images on the screen. The original resolution of each image is 20*20 and I am scaling them to 80*80 with nearest neighbor before drawing them.
I currently use AffineTransform to scale them up when the program is initialized, and redraw the enlarged images every frame in different positions.
Seeing as the target framerate is about 60 fps, I need to find a way to draw them faster, preferably so that it doesn't render them as 80*80 bitmaps. I tried Graphics2D's drawImage method with the width and height parameters, but it actually slowed my program down.
In pseudocode:
Image image; //loaded from 20*20 png file
public void init(){
image = resize(image, 80, 80);
}
public void repaint(Graphics g){
g.drawImage(image, 0, 0, null);
}
I also tried:
Image image;
public void repaint(Graphics g){
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g.drawImage(image, 0, 0, 80, 80, null);
}
Is there a solution to my problem?
There was a similar question about that: Load and Resize Image
Here is my answer: Load and Resize Image
I hope I could help.
I have an image that is too tall for my JFrame even when it is maximized. I want to dynamically resize it so that the image will never be clipped by the top or bottom of the JFrame. I have inserted the image within a JLabel as an ImageIcon. I have tried setting the maximum size to no avail. How do I ensure that the height of the image will never be larger than the JFrame? I would ideally like to keep the ratio of height to width constant. The image is in a portrait orientation. Any ideas?
public class myClass extends JFrame {
private void initGUI(){
pane = getContentPane();
pane.setLayout(new BorderLayout());
next = new JButton("Next");
previous = new JButton("Previous");
page = new JLabel(loadImg());
page.setMaximumSize(this.getSize());
pane.add(next, BorderLayout.EAST);
pane.add(previous, BorderLayout.WEST);
pane.add(page, BorderLayout.CENTER);
}
}
I would ideally like to keep the ratio of height to width constant.
Check out Darryl's Stretch Icon. It will shrink/grow depending on the space available, while maintaining the width/height ratio.
You can try overriding the paintComponent(Graphics g) method and drawing the resized image yourself.
page = new JLabel(loadIMG()){
#Override
paintComponent(Graphics g)
{
//So we don't kill default behaviour
super.paintComponent(g);
int scaledWidth, scaledHeight;
//pseudo-code
scale and store into scaledWidth and scaledHeight;
render with g.drawImage(icon, x, y, scaledWidth, scaledHeight, null);
}
};