This is my first time on stackoverflow and I am having an issue which I can't seem to get to the bottom of. I am trying to independently develop a small desktop game which uses a class called "Frame.java" to create a JFrame with all the menus and such that I need using a method called "create()", which returns the frame. I'm also using another class called "MainPanel.java", which extends JPanel, to create an instance of MainPanel to add to the frame's contentpane. However, when I run all the code in my little driver program, nothing seems to be displaying. any help would be appreciated!
public class MainPanel extends JPanel{
//the background image of the game
private BufferedImage img = null;
//GUI components of the game
private JPanel gameWindow, gameWindowHolder, gameInfoHolder, LevelPanel, RevenuePanel,
ActionPanel, TimePanel;
public MainPanel(String path, int width, int height){
//create BufferedImage based on path
img = new ImageHelper().createBufferedImage(path);
//use img to create JPanel gameWindow
gameWindow = ImageHelper.makeImageComponent(img, width, height);
gameInfoHolder = new JPanel();
gameInfoHolder.setPreferredSize(new Dimension(width+10, height+10));
gameInfoHolder.setBackground(Color.black);
gameInfoHolder.add(gameWindow);
//set size of this MainPanel
setPreferredSize(new Dimension(width+300, height+10));
//add gameInfoHolder to MainPanel
add(gameInfoHolder);
}
public void paint(Graphics g) {
super.paintComponent(g);
}
}
public class Driver {
public static void main( String []args){
JFrame frame = Frame.create();
JPanel panel = new MainPanel("images/backgrounds/jessicaAlba.jpg", 330, 500);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
public class ImageHelper {
//
//Returns an ImageIcon object based on the path
//
public ImageIcon createImageIcon(String path, String description){
URL imgURL = getClass().getResource(path);
if (imgURL != null)
return new ImageIcon(imgURL, description);
else {
System.err.println("Couldn't find this file: " + path + ". Check path.");
return null;
}
}
//
//Returns an Image object based on the path
//
public Image createImage(String path){
URL imgURL = getClass().getResource(path);
Toolkit kit = Toolkit.getDefaultToolkit();
if (imgURL != null){
return kit.createImage(imgURL);
}
else {
System.err.println("Couldn't find this file: " + path + ". Check path.");
return null;
}
}
//
//Returns a BufferedImage object based on the path
//
public BufferedImage createBufferedImage(String path){
BufferedImage image;
URL imgURL = getClass().getResource(path);
try
{
image = ImageIO.read(imgURL);
}
catch (IOException e)
{
System.err.println("Couldn't find this file: \""+ path +"\". Check path.");
return null;
}
return image;
}
//
//Returns a JPanel object composed of the image found in the path.
//
public static JPanel makeImageComponent(String path, int width, int height){
BufferedImage image;
JLabel picLabel;
ImageIcon icon;
JPanel panel = new JPanel();
JPanel panel2 = new JPanel();
ImageHelper h = new ImageHelper();
image = h.createBufferedImage(path);
image = resize(image, width, height);
icon = new ImageIcon(image);
panel.setPreferredSize(new Dimension(width, height));
panel2.setPreferredSize(new Dimension(width+10, height+10));
panel2.setBackground(Color.black);
picLabel = new JLabel(icon);
panel.add(picLabel);
panel2.add(panel);
return panel2;
}
//
//Returns a JPanel object composed of the BufferedImage object in the argument
//
public static JPanel makeImageComponent(BufferedImage image, int width, int height){
JLabel picLabel;
ImageIcon icon;
JPanel panel = new JPanel();
image = resize(image, width, height);
icon = new ImageIcon(image);
panel.setPreferredSize(new Dimension(width, height));
picLabel = new JLabel(icon);
panel.add(picLabel);
return panel;
}
//
//Resizes the BufferedImage object to the specified new width and new height.
//
public static BufferedImage resize(BufferedImage img, int newW, int newH) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
g.dispose();
return dimg;
}
}
Nothing is displayed as you're short-circuiting the paint 'stack' with super.paintComponent so no child components will be painted.
public void paint(Graphics g) {
super.paintComponent(g);
}
As this is really serving no purpose it can be removed and the added panels will be displayed.
Related
I've been searching for an answer, but everything else comes very close, but isn't the problem I'm having.
So my main class creates a new JFrame, adds a panel as the content panel, and I add a scrollpanel to that content panel.
Now I create some of my extending JPanel classes, add them to the scroll pane and see nothing but an empty frame.
And I have checked to make sure there is indeed a list of FTPFile's
Here is the main code:
public browser(ftpHandler _FTP) {
FTP = _FTP;
Panels = new ArrayList<JPanel>();
frame = new JFrame("File Browser");
frame.setContentPane(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(750, 500));
frame.setSize(frame.getPreferredSize());
frame.setMinimumSize(frame.getSize());
mainPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
listFiles();
frame.pack();
frame.setVisible(true);
}
public void listFiles(){
Panels.clear();
FTPFile[] list = null;
try {
list = FTP.listFiles();
} catch (Exception e) {
e.printStackTrace();
}
for(FTPFile file : list){
fileObject FO = new fileObject(file);
Panels.add(FO);
scrollPane.add(FO);
}
scrollPane.updateUI();
}
And my extended JPanel, fileObject
public class fileObject extends JPanel {
private FTPFile file;
private JLabel Label;
private ImageIcon Icon;
private int FileType;
private final int IconSize = 25;
private final Dimension panelSize = new Dimension(150, 40);
public fileObject(FTPFile FILE){
file = FILE;
FileType = file.getType();
this.setSize(panelSize);
this.setPreferredSize(panelSize);
this.setMinimumSize(panelSize);
this.setLayout(new WrapLayout());
switch (FileType){
case FTPFile.TYPE_DIRECTORY:
Icon = resizeImage(new ImageIcon(getClass().getResource("/com/taylor/48px/folder.png")),IconSize);
break;
case FTPFile.TYPE_FILE:
try {
String FileExtension = file.getName().substring(file.getName().lastIndexOf(".")+1);
Icon = resizeImage(new ImageIcon(getClass().getResource("/com/taylor/48px/"+FileExtension+".png")),IconSize);
} catch(Exception e) {
Icon = resizeImage(new ImageIcon(getClass().getResource("/com/taylor/48px/_blank.png")),IconSize);
}
break;
case FTPFile.TYPE_LINK:
Icon = resizeImage(new ImageIcon(getClass().getResource("/com/taylor/48px/_page.png")),IconSize);
break;
}
Label = new JLabel(file.getName(), Icon, JLabel.LEFT);
this.add(Label);
}
private ImageIcon resizeImage(ImageIcon II, int Size){
Image img = II.getImage();
BufferedImage resizedImage = new BufferedImage(Size, Size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = resizedImage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, 0, 0, Size, Size, null);
g2.dispose();
return new ImageIcon(resizedImage);
}
}
I got this working, it turns out I was had my panels set up wrong, they were setup like this:
JFrame
--mainPanel
----scrollPane
And I was adding my extended panel to the scrollPane
And this seemed to not work, so I added another panel inside the scrollPane and started adding my extended panels to this new panel and it started working!
In JFrame i have some buttons and BufferedImgae which will be used to draw on it some shapes and pictures using my own methods ( drawLine, drawing raster picture pixel by pisel and so on).
Here is how i add things to JFrame
public class Main extends javax.swing.JPanel {
JPanel panel;
JFrame fr;
Graphics2D g2;
ImageIcon icon;
BufferedImage img;
public void init()
{
fr = new JFrame("Lab 2");
fr.setMinimumSize(new Dimension(1350, 650));
fr.setMaximumSize(fr.getMinimumSize());
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel glowny = new JPanel(new BorderLayout());
glowny.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
glowny.add(getBorderCenter(), BorderLayout.CENTER);
fr.add(glowny);
fr.pack();
fr.setVisible(true);
}
private JScrollPane getBorderCenter()
{
img = new BufferedImage( fr.getWidth()-40, fr.getHeight()-40-50, BufferedImage.TYPE_INT_RGB); //20+20 odstępy w glowny, 50 - szerokość paska z guzikami
icon = new ImageIcon(img);
return new JScrollPane(new JLabel(icon));
}
public static void main(String [] args)
{
Main m = new Main();
m.init();
}
}
Then i try to draw on BufferedImage using double buffering.
The following example change BufferedImage color from black (current) to white.
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("paintComponent");
WritableRaster raster = img.getRaster();
DataBuffer db = raster.getDataBuffer();
int[] pixels = ((DataBufferInt)db).getData();
int adres = 0;
for (int y = 0; y < img.getHeight(); y++)
{
adres = y * img.getWidth();
for (int x = 0; x < img.getWidth(); x++)
{
pixels[adres] = 16777215;
adres += 1;
}
}
Graphics2D g2dComponent = (Graphics2D) g;
g2dComponent.drawImage(img, null, 0, 0); // draw buffer on screen
}
As i understand repaint() force calling paintComponent(). The problem is that it doesnt matter how i call repaint()
fr.repaint();
glowny.repaint();
repaint();
its never called.
You never add Main to the GUI. You need to add the JPanel that overrides the paintComponent, the this, to the GUI somewhere and you don't. For example, you would need somewhere something like:
someComponentShownInGui.add(this);
I would get rid of the glowny variable and instead use this.
i.e.,
public void init()
{
fr = new JFrame("Lab 2");
fr.setMinimumSize(new Dimension(1350, 650));
fr.setMaximumSize(fr.getMinimumSize());
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// JPanel glowny = new JPanel(new BorderLayout());
// glowny.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// glowny.add(getBorderCenter(), BorderLayout.CENTER);
// fr.add(glowny);
setLayout(new BorderLayout();
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
add(getBorderCenter(), BorderLayout.CENTER);
fr.add(this);
fr.pack();
fr.setVisible(true);
}
Note that anything components added to the drawing JPanel will cover up its image, and so you may need to make some non-opaque.
You should add all you components inside a JPanel then override paintComponent method of the panel. (JFrame doesn't have paintComponet but paint method and it's not recommanded to override it)
I'm trying to create a buffered image from the contents of a JScrollpane. The Jscrollpane dimesions are 250x200. The contents spillover and only the visible section gets captured in the image. I'm using Java graphics 2D.
Is there a way to capture the complete contents of the scrollpage?
Just paint the contents to the BufferedImage, and not the scroll pane.
For example:
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
final Image image =
new ImageIcon("stackoverflow.png").getImage();
JPanel imagePanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(this),
image.getHeight(this));
}
};
JScrollPane pane = new JScrollPane(imagePanel);
pane.setPreferredSize(new Dimension(200, 200));
JOptionPane.showMessageDialog(null, pane);
BufferedImage newImage = getImageFromComponent(imagePanel);
JLabel label = new JLabel(new ImageIcon(newImage));
JOptionPane.showMessageDialog(null, label);
}
});
}
private static BufferedImage getImageFromComponent(Component component) {
BufferedImage img = new BufferedImage(
component.getWidth(), component.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = img.createGraphics();
component.paint(g);
g.setFont(new Font("impact", Font.PLAIN, 30));
g.drawString("Image of Panel", 40, 50);
g.dispose();
return img;
}
}
First the panel is put inside scroll pane.
When we close it, the contents of the panel are drawn to to a BufferedImage, and added to a label.
I'm trying to create an 8x8 grid composed of pre made images to be used for a board game, however I am having difficulty loading the images.
Dimension Size = new Dimension(400, 400);
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(Size);
getContentPane().add(layeredPane);
board.setLayout(new GridLayout(8,8));
board.setPreferredSize(Size);
board.setBounds(0, 0, Size.width, Size.height);
layeredPane.add(board, JLayeredPane.DEFAULT_LAYER);
// Load squares to board
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
JPanel square = new JPanel( new BorderLayout() );
square. // Load .jpg here?????
board.add( square );
}
}
The only method I know is ImageIcon, but that doesn't seem to work... So I'm stuck.
Any help would be appreciated, Thanks.
ImageIcon should work fine. See the Swing tutorial on How to Use Icons for more information and examples.
Try this code snippet, adapted from java2s.com:
class ImagePanel extends JPanel {
private Image img;
public ImagePanel(URL imgURL) {
this(new ImageIcon(imgURL).getImage());
}
public ImagePanel(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(this), img.getHeight(this));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
#Override
public void paintComponent(Graphics g) {
super.paint(g);
g.drawImage(img, 0, 0, this);
}
}
You can add those ImagePanels inside the JPanel
Any other errors aside, I need a way of converting my Color grayScale into an int. When I plug in the Color, I get an error. setRGB method takes an x, a y, and an rgb int as parameters. How do I change my Color into an int?
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
public class Picture{
Container content;
BufferedImage image, image2;
public Picture(String filename) {
File f = new File(filename);
//assume file is the image file
try {
image = ImageIO.read(f);
}
catch (IOException e) {
System.out.println("Invalid image file: " + filename);
System.exit(0);
}
}
public void show() {
final int width = image.getWidth();
final int height = image.getHeight();
JFrame frame = new JFrame("Edit Picture");
//set frame title, set it visible, etc
content = frame.getContentPane();
content.setPreferredSize(new Dimension(width, height));
frame.pack();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//add a menubar on the frame with a single option: saving the image
JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar);
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
JMenuItem saveAction = new JMenuItem("Save");
fileMenu.add(saveAction);
JMenuItem grayScale = new JMenuItem("Grayscale");
fileMenu.add(grayScale);
grayScale.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
grayscale(width, height);
}
});
//add the image to the frame
ImageIcon icon = new ImageIcon(image);
frame.setContentPane(new JLabel(icon));
//paint the frame
frame.setVisible(true);
frame.repaint();
}
public void grayscale(int width, int height) {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
Color color = new Color(image.getRGB(i, j));
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
int rGray = red*(1/3);
int gGray = green*(2/3);
int bGray = blue*(1/10);
Color grayScale = new Color(rGray, gGray, bGray);
image.setRGB(i,j, grayScale);
}
}
show();
}
public static void main(String[] args) {
Picture p = new Picture(args[0]);
p.show();
}
}
As per comment by trashgod.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.image.*;
public class Picture{
Container content;
BufferedImage image;
BufferedImage image2;
public Picture(BufferedImage image) {
this.image = image;
grayscale();
}
public void show() {
JFrame frame = new JFrame("Edit Picture");
//set frame title, set it visible, etc
content = frame.getContentPane();
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//add the image to the frame
ImageIcon icon = new ImageIcon(image2);
frame.setContentPane(new JLabel(icon));
frame.pack();
//paint the frame
frame.setVisible(true);
}
public void grayscale() {
// create a grayscale image the same size
image2 = new BufferedImage(
image.getWidth(),
image.getHeight(),
BufferedImage.TYPE_BYTE_GRAY);
// convert the original colored image to grayscale
ColorConvertOp op = new ColorConvertOp(
image.getColorModel().getColorSpace(),
image2.getColorModel().getColorSpace(),null);
op.filter(image,image2);
show();
}
public static void main(String[] args) {
int size = 120;
int pad = 10;
BufferedImage bi = new BufferedImage(
size,
size,
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0,0,size,size);
g.setColor(Color.YELLOW);
g.fillOval(pad,pad,size-(2*pad),size-(2*pad));
g.dispose();
Picture p = new Picture(bi);
p.show();
}
}
image.setRGB(i, j, grayScale.getRGB());
Take a look at what values (1/3), (2/3), and (1/10) actually have, then note that you are multiplying your red, green, and blue values by those numbers.
The color is an Object. An rgb is an int. Use colorName.getRGB() to get the integer RGB value of that color.