i wrote this code for showing some simple picture on the applet screen, but the picture doesnt show untill i resize the applet window, what can i do to overcome it?
public class Test extends JApplet {
public void init () {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createGUI();
}
});
}
public void start() {
}
public void createGUI() {
getContentPane().add(new GUIThing(getImage(getCodeBase(), "gladiator.gif")));
}
}
public class GUIThing extends JPanel {
Image image;
public GUIThing(Image i2) {
image=i2;
}
public void paintComponent(Graphics g) {
Graphics2D g2=(Graphics2D) g;
g2.drawImage(image,100,100,100, 100, null);
}
}
Try passing the applet context to the drawImage method, this allows the appet to be notified when the image is loaded and it will repaint itself
g2.drawImage(image,100,100,100, 100, this);
And, if you're really desperate, call invalidate() repaint() in the start method
UPDATE WITH EXAMPLE
This is the code that I used. I had no issue with loading the image:
public class TestApplet extends JApplet {
public void init() {
System.out.println("Init..." + EventQueue.isDispatchThread());
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
createGUI();
}
});
}
public void start() {
System.out.println("Start..." + EventQueue.isDispatchThread());
}
public void createGUI() {
URL documentBase = getDocumentBase();
System.out.println(documentBase);
System.out.println(getCodeBase());
// file:.../build/TestApplet.html
// file:.../build/classes/
Image image = getImage(documentBase, "MT-vol-6-STOP-image-Kogumiko-megatokyo-11434773-1559-1852.jpg");
System.out.println("image = " + image);
getContentPane().add(new GUIThing(image));
}
public class GUIThing extends JPanel {
Image image;
public GUIThing(Image i2) {
image = i2;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(image, 0, 0, this);
g2.setColor(Color.RED);
g2.drawLine(0, 0, getWidth(), getHeight());
}
}
}
Wow, it's been a long time since I played with applets. I changed your code from using the code base to the document base it seems to have worked. I was loading an image of 1559x1852 pixels with little to no delay (locally)
Double check your applet tag in you HTML file as well. I was using
<APPLET codebase="classes" code="stack/TestApplet.class" width=350 height=200></APPLET>
Through the applet viewer. Note the code base is different from the document base!!
My image was in the same location as the HTML file
Related
After I start my applet every component is drawn alright, besides my background image that is drawn with about a half second delay. I deleted my thread thinking it's maybe the cause of my problem, but it's not, so i didn't include it here.... I use Double Buffering, because I would have flickering of my components that are repainted by thread. I tried to provide as little code as possible....
public class balg extends Applet implements Runnable {
private Image i;
private Graphics doubleG;
URL url;
Image city; //background image
public void init(){
setSize(800, 600);
try{
url = getDocumentBase();
}catch(Exception e){
}
city = getImage(url , "multiplen/images/SPACE.png");
}
public void start(){
Thread thread = new Thread(this);
thread.start();
}
public void run(){
// here goes the repiant();
}
public void stop(){
}
public void destroy(){
}
#Override
public void update(Graphics g) {
if(i == null){
i = createImage(this.getSize().width, this.getSize().height);
doubleG = i.getGraphics();
}
doubleG.setColor(getBackground());
doubleG.fillRect(0, 0, this.getSize().width, this.getSize().height);
doubleG.setColor(getForeground());
paint(doubleG);
g.drawImage(i, 0,0, this);
}
public void paint(Graphics g){
g.drawImage(city,(int) 800 , 0 , this); // it's drawn here
String s = "15";
g.setColor(Color.BLACK);
g.drawString(s, getWidth() - 150, 50);
}
}
It takes that much time to read the image, about 100-200 ms.
Simple problem for Swing regular costumers.
The idea is to load an image and use it as a background of a JPanel through a JComponent object. It seems to load just fine as the image information from toString() method is loading properly and the paintComponent() method is running, but for some reason it is not rendering correctly inside the JFrame leading to an empty frame. Here's the code:
RicochetFrame.java
public class RicochetFrame extends JFrame {
RicochetStartPanel startPanel;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
RicochetFrame window = new RicochetFrame();
window.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public RicochetFrame() throws IOException {
startPanel = new RicochetStartPanel();
this.getContentPane().add(startPanel);
this.setBounds(0, 0, 500, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//this.pack();
this.setVisible(true);
}
}
RicochetStartPanel.java
public class RicochetStartPanel extends JPanel {
RicochetStartPanel() throws IOException {
BufferedImage myImage = ImageIO.read(new File("frame_bg.jpg"));
this.add(new RicochetImagePanel(myImage));
this.setVisible(true);
this.validate();
this.repaint();
}
}
RicochetImagePanel.Java
public class RicochetImagePanel extends JComponent {
private Image image;
public RicochetImagePanel(Image image) {
this.setVisible(true);
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
}
Your RicochetImagePanel is sizing itself to its preferred size => [0, 0]. Override its getPreferredSize() to return the dimensions of the image (if not null). Better still, why not simply display the image as an ImageIcon in a JLabel?
I am creating a lightweight client for the game Runescape that has various user features such as custom keybinds/hotkeys. I'm pretty good with java and swing, but AWT and applets I am mediocre at best. I was able to get the applet downloaded and displayed on a JPanel and then in a JFrame and the game runs perfectly so far. However, when adding features I ran into a problem when I tried to implement a screenshot function to the client.
It's hard to post a concise working example so I'll post the methods I was trying based off of some other SO answers I was reading. I tried creating BufferedImage from the Applet, applet Canvas, the JPanel it is handled by, and the JFrame.
Here are some things I tried to create a screenshot from the Applet canvas:
public BufferedImage getScreenShot() {
//getting the applet canvas
Canvas canvas = (Canvas) this.getApplet().getComponent(0);
//bufferedImage to draw to
BufferedImage image = new BufferedImage(canvas.getWidth(), canvas.getHeight(), BufferedImage.TYPE_INT_ARGB);
//Graphics2D g2=(Graphics2D)image.getGraphics();
//test.print(g2);
//g2.dispose();
Graphics g = image.getGraphics();
Image image2 = canvas.createImage(canvas.getWidth(), canvas.getHeight());
canvas.print(g);
System.out.println("Canvas Size: " + canvas.getSize().width + " x " + canvas.getSize().height);
return image;
}
This one I tried in the JPanel class which holds only the Applet:
public BufferedImage getScreenShotFINAL(){
BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
applet.paint(bi.createGraphics());
return bi;
}
I understand that the idea here is to create an off-screen BufferedImage, then to create a Graphics2d object and to then call the applet's paint() method to paint to the off-screen image. I tried this solution from here:
public BufferedImage getScreenShotFINAL2() {
Dimension size = applet.getSize();
BufferedImage offScreenImage = (BufferedImage) applet.createImage(size.width, size.height);
Graphics2D g2 = offScreenImage.createGraphics();
g2.setBackground(applet.getBackground());
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.clearRect(0, 0, size.width, size.height);
applet.paint(g2);
return offScreenImage;
}
When saving the BufferedImages these and other methods I tried to a file the images just show up as black, just the default background color. Is there a good way to just get a BufferedImage from the JPanel which would include the Applet so I never have to deal with the Applet directly? Another thing, I had to override the java Canvas class in order to get the game to display (because it is double buffered I believe). I tried following a bunch of solutions from here but had no success. Any suggestions would be greatly appreciated. I also can provide a link to the full project or the custom Canvas project if you would like. Thanks!
EDIT
Here is the Canvas class which overrides the java AWT one. Didn't write it, followed a tutorial for this one and I think this is where the problem is, because the paint() method only calls clearRect():
package java.awt;
import Client.Client;
import java.awt.image.BufferStrategy;
import java.awt.peer.CanvasPeer;
import javax.accessibility.*;
import loaders.ClientPool;
public class Canvas extends Component implements Accessible {
private Client client = null;
private static final String base = "canvas";
private static int nameCounter = 0;
private static final long serialVersionUID = -2284879212465893870L;
public Canvas() {
super();
}
public Canvas(GraphicsConfiguration config) {
this();
setGraphicsConfiguration(config);
}
#Override
void setGraphicsConfiguration(GraphicsConfiguration gc) {
synchronized(getTreeLock()) {
CanvasPeer peer = (CanvasPeer)getPeer();
if (peer != null) {
gc = peer.getAppropriateGraphicsConfiguration(gc);
}
super.setGraphicsConfiguration(gc);
}
}
#Override
public Graphics getGraphics(){
if (this.client == null) {
this.client = ClientPool.getClient(this);
}
if (client != null) {
//call custom draw functions for specific client. for drawing/double buffering
return client.drawGraphics((Graphics2D) super.getGraphics());
}
return super.getGraphics();
}
#Override
String constructComponentName() {
synchronized (Canvas.class) {
return base + nameCounter++;
}
}
#Override
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = getToolkit().createCanvas(this);
super.addNotify();
}
}
#Override
public void paint(Graphics g) {
g.clearRect(0, 0, width, height);
}
#Override
public void update(Graphics g) {
g.clearRect(0, 0, width, height);
super.paint(g);
}
#Override
boolean postsOldMouseEvents() {
return true;
}
#Override
public void createBufferStrategy(int numBuffers) {
super.createBufferStrategy(numBuffers);
}
#Override
public void createBufferStrategy(int numBuffers,
BufferCapabilities caps) throws AWTException {
super.createBufferStrategy(numBuffers, caps);
}
#Override
public BufferStrategy getBufferStrategy() {
return super.getBufferStrategy();
}
#Override
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTCanvas();
}
return accessibleContext;
}
protected class AccessibleAWTCanvas extends AccessibleAWTComponent
{
private static final long serialVersionUID = -6325592262103146699L;
public AccessibleRole getAccessibleRole() {
return AccessibleRole.CANVAS;
}
}
}
I'm not that familiar with Java and I'm a little clueless about my current problem.
I'm trying to draw an Image within a separate class of my Main JFrame, but it
always draw just a little piece of the picture (maybe 10x10px).
(A test with a Label worked)
Maybe I didn't used the g.drawImage method correct, or the JPanel don't have enough space??
MainWindow:
public class Deconvolutioner extends JFrame {
Draw z;
Picturearea picturearea;
class Draw extends JPanel {
public void paint(Graphics g) {
}
}
public Deconvolutioner() {
setTitle("Deconvolutioner");
setLocation(30,1);
setSize(1300,735);
super.setFont(new Font("Arial",Font.BOLD,11));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout flow = new FlowLayout(FlowLayout.CENTER);
this.setLayout(flow);
picturearea = new Picturearea();
this.add(picturearea);
add(z = new Draw());
setVisible(true);
}
class Open implements ActionListener {
public void actionPerformed(ActionEvent e) {
JFileChooser fileOpen = new JFileChooser();
FileFilter filter = new FileNameExtensionFilter("png & jpg files", "png",
"jpg");
fileOpen.addChoosableFileFilter(filter);
int returnVal = fileOpen.showDialog(null, "Open file");
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
String path = fileOpen.getSelectedFile().getPath();
URL url = new File(path).toURI().toURL();
BufferedImage img = ImageIO.read(url);
picturearea.setPicture(img);
} catch (IOException ex) {
System.err.println("Some IOException accured (set the right path?): ");
System.err.println(ex.getMessage());
}
} else {
}
repaint();
}
}
And the separate class:
public class Picturearea extends JPanel {
public BufferedImage image;
Draw z;
public Picturearea() {
add(z = new Draw());
setVisible(true);
}
class Draw extends JPanel {
#Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
}
public void setPicture(BufferedImage picture) {
try {
image = picture;
} catch (Exception e) {
System.err.println("Some IOException accured (did you set the right path?): ");
System.err.println(e.getMessage());
}
repaint();
}
}
I'm grateful for every help.
thanks for your time.
You are using FlowLayout for JFrame's contentPane's layout. FlowLayout obeys component's preferredSize. Try setting preferredSize of your pictureArea by pictureArea.setPreferredSize(Dimension) or overriding getPreferredSize(Dimension) function in PictureArea class.
you are using paint(Graphics g) for custom painting:
#Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
Do not override paint() for custom painting override paintComponent(Graphics g) instead. And You may need to scale your image to fit in the size of the JPanel. you can use g.drawImage(x, y, width, height, observer) function if you need to scale your image.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
I created a component to display Image in jPanel.But its not showing the image during design time.how to show Image on design time?
public class JImagePanel extends JPanel {
private BufferedImage _img=null;
public JImagePanel() {
super();
}
public void setImage(URL img) {
try{
this._img = ImageIO.read(img);
validate();
repaint();
}catch(Exception err){
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if(this._img!=null)
g.drawImage(_img, 0, 0, getWidth(), getHeight(), this);
}
}
if you want to display Icon/ImageIcon only, then better would be look for JLabel as painting background by using paintComponent(Graphics g)