I'm doing a program in Netbeans
.. and I need to display the content of the folder (there are images) in a JPanel
... display every image in jlabel
.... I did this code, but its not working
...... I create a interface with a JButton and JPanel:
public class MyInterface extends javax.swing.JFrame
{
/** Creates new form NewJFrame1 */
public MyInterface()
{
initComponents();
}
private File files;
private JFileChooser es = new JFileChooser();
String path;
JLabel label;
public List<ImageIcon> pictures = new ArrayList<ImageIcon>();
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
if (es.showOpenDialog(jPanel1) == JFileChooser.APPROVE_OPTION)
{
files = es.getSelectedFile();
path = files.getAbsolutePath();
return;
}
label.setIcon(pictures.get(WIDTH));
files = null;
return;
}
private JLabel getLabel(BufferedImage[] images)
{
for (int j = 0; j < images.length; j++)
{
pictures.add(new ImageIcon(images[j]));
}
label = new JLabel(pictures.get(0));
label.setHorizontalAlignment(JLabel.CENTER);
return label;
}
private JPanel draw()
{
JPanel panl = new JPanel();
for (int j = 0; j < pictures.size(); j++)
{
panl.getBorder();
}
JPanel panel = new JPanel();
panl.addAncestorListener(null);
panl.add(panl);
return panel;
}
}
hard to say something and wise
1) maybe there isn't any reason for create JLabels and JPanels on the fly
2) if you want to display only one Image in one moment then
create JFrame
put there JLabel and JButton
use Icon for Image/BufferedImage, put this Icon to the JLabel
3) if you want to display more than one Images (let's to say up to 20-50 Images) then use GridLayout for JLabels contains Icon
4) if number of Images isn't limited somehow then use JList
It's not entirely clear what you are trying to do, your code doesn't compile as shown, and it's a bit of a mess. Some pointers though:
In draw(), you are adding a JPanel to itself, which is not a good sign. Then you return a different panel that has not been modified. Sort out the panel and panl naming to fix this.
In getLabel(), which isn't actually called anywhere, you return one label created from the first image. So you will only be able to display one of the images.
In jButton1ActionPerformed you return early if the user selects a file, so the path will be set but it's not clear that anything else happens.
Related
I'm writing a little photo application (asked some questions before) and I have one problem which I cannot resolve. The idea is that there are two sections: the upper one is for an overview (using thumbnails) and the lower one shows the selected image in it's full size. I cannot use ImageIO (required by my lecturer).
I'm using a JList for the overview but most images are not visible. I chose a folder with about 20 images and only 2 show up. And one of them isn't even centered.
For some reason, if I delete those lines:
thumbnaillist.setFixedCellWidth(thumbW);
thumbnaillist.setFixedCellHeight(thumbH);
One image shows up that wasn't visible before, but now the other two disappear.
This is my code:
public class PVE extends JFrame {
private JFileChooser fileChoose;
//MenuBar
private JMenuBar menubar;
private JMenu file;
private JMenuItem openFolder;
private JMenuItem exit;
//Thumbnails
private JList thumbnaillist;
private DefaultListModel<ImageIcon> listmodel;
private JScrollPane tscroll;
private ImageIcon thumbs;
private int thumbW = 100;
private int thumbH = 100;
//for full size view
private JPanel imgview;
public PVE() {
setLayout(new BorderLayout());
//MenuBar
menubar = new JMenuBar();
file = new JMenu("File");
openFolder = new JMenuItem("Open folder...");
exit = new JMenuItem("Quit");
file.add(openFolder);
file.addSeparator();
file.add(exit);
menubar.add(file);
setJMenuBar(menubar);
fileChoose = new JFileChooser();
openFolder.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
fileChoose.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChoose.showOpenDialog(null);
File chosenDir = fileChoose.getSelectedFile();
loadToThumbView(chosenDir);
}
});
//Thumbnail view
listmodel = new DefaultListModel();
thumbnaillist = new JList(listmodel);
thumbnaillist.setLayoutOrientation(JList.HORIZONTAL_WRAP);
thumbnaillist.setFixedCellWidth(thumbW);
thumbnaillist.setFixedCellHeight(thumbH);
thumbnaillist.setVisibleRowCount(1);
tscroll = new JScrollPane(thumbnaillist, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
tscroll.setPreferredSize(new Dimension(0, 100));
add(tscroll, "North");
//for full size view
imgview = new JPanel();
imgview.setBackground(Color.decode("#f7f7f7"));
add(imgview, "Center");
setTitle("Photo Viewer");
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
} catch (Exception e) {
}
setSize(700, 700);
setLocation(200, 200);
setVisible(true);
}
public void loadToThumbView(File folder) {
listmodel.removeAllElements();
File[] imgpaths = folder.listFiles();
for (int j = 0; j < imgpaths.length; j++) {
listmodel.addElement(resizeToThumbnail(new ImageIcon(imgpaths[j].toString())));
}
}
public ImageIcon resizeToThumbnail(ImageIcon icon) {
Image img = icon.getImage();
BufferedImage bf = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = bf.createGraphics();
g.drawImage(img, 0, 0, thumbW, thumbH, null);
ImageIcon kB = new ImageIcon(bf);
return kB;
}
public static void main(String argv[]) {
PVE pv = new PVE();
}
}
Your problem is because of the way you're scaling your images.
I'm not exactly sure why but I guess it has something to do with the BufferedImage#createGraphics() call and that I was able to reproduce the problem with .jpg images while .png files were correctly painted.
However if you scale your images instead of converting them to a BufferedImage and getting a new ImageIcon from it, you get the correct output:
public ImageIcon resizeToThumbnail(ImageIcon icon) {
Image img = icon.getImage();
Image scaled = img.getScaledInstance(thumbW, thumbH, Image.SCALE_SMOOTH);
return new ImageIcon(scaled);
}
This is the folder I used to test:
And the outputs with your code and mine:
Important notes
And as as a recommendation don't make a window that big if all you're using is that little bar above. If you're adding something else below, then it's ok but for now it's not that "user friendly" (IMHO). Instead of JFrame#setSize() you could try using JFrame#pack() method so your frame resizes to it's preferred size.
Some other things I noted in your program:
You're not placing it inside the Event Dispatch Thread (EDT) which is dangerous since your application won't be Thread safe that way. You can change that if you change your main method as follows:
public static void main(String argS[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
PVE pv = new PVE();
}
});
}
You're setting the JScrollPane preferred size, instead you should override its getPreferredSize() method, see Should I avoid the use of setPreferred|Maximum|MinimumSize methods in Java Swing? (YES)
You're extending JFrame, you should instead create an instance of it unless you're overriding one of its methods (and you're not, so don't do it) or you have any good reason to do it. If you need to extend a Container you should extend JPanel instead, as JFrame is a rigid container which cannot be placed inside another one. See this question and this one.
I think I'm not missing anything, and hope this helps
Your “scaled” images are actually images which are the same size as the original image, but are blank except for a scaled version drawn in the upper left corner. That upper left corner is clipped out of view in each rendered cell (at least for the somewhat large images I tested with).
The scaled image needs to be created with the thumbnail size, not the size of the original image. Meaning, change this:
BufferedImage bf = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
to this:
BufferedImage bf = new BufferedImage(thumbW, thumbH, BufferedImage.TYPE_INT_ARGB);
I am trying to take a file full of images and read them into an ArrayList to make a deck of cards. Then display it on a JPanel. Here is my code:
private static class CardDealer extends JFrame
{
private ImageIcon[] cards = new ImageIcon[52];
private ArrayList<ImageIcon> deck = new ArrayList<ImageIcon>();
private JButton deal;
private JPanel faceDown, faceUp, button;
private JLabel backs, fronts;
private Random card = new Random(52);
public CardDealer() throws FileNotFoundException
{
File images = new File("src/Images");
Scanner file = new Scanner(images);
for(int i=0; i<cards.length; i++)
{
cards[i] = new ImageIcon(Arrays.toString(images.list()));
deck.add(cards[i]);
}
//setTitle to set the title of the window
setTitle("Card Dealer");
//set the application to close on exit
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Call all our build panel methods
buildButtonPanel();
buildFaceDownPanel();
buildFaceUpPanel();
setLayout(new BorderLayout());
add(button, BorderLayout.SOUTH);
add(faceDown, BorderLayout.WEST);
add(faceUp, BorderLayout.EAST);
pack();
validate();
setVisible(true);
}
private void buildButtonPanel()
{
button = new JPanel();
deal = new JButton("Deal");
deal.addActionListener(new buttonListener());
button.add(deal);
}
private void buildFaceDownPanel()
{
faceDown = new JPanel();
backs = new JLabel();
backs.setText("Cards");
backs.setIcon(new ImageIcon("Blue.bmp"));
faceDown.add(backs);
}
private void buildFaceUpPanel()
{
faceUp = new JPanel();
fronts = new JLabel();
faceUp.add(fronts);
}
private class buttonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
fronts.setIcon(deck.get(card.nextInt()));
}
}
}
public static void main(String[] args) throws FileNotFoundException
{
new CardDealer();
}
I don't know why no images show up when I run the program. Even the backs JLabel image does not show when running. Any help is appreciated!!
Lets start with File#list will return an array of File objects which are contained within the specified file location, this makes
cards[i] = new ImageIcon(Arrays.toString(images.list()));
very worrisome for two reasons, apart from the fact that you are simply converting a list of files into a String, doing this cards.length is woefully inefficient...
Next, you should NEVER reference src in any path within your code, once built and packaged, src will no longer exist and you won't be able to access your "files" like normal files (as they will likely be embedded inside your jar file).
This raises another issue, since it's not easy to list resources embedded within a jar file (when you don't even know the name of the Jar file), you need a different approach.
One might be to name the images in a common, sequential manner, like /images/Card0.png, /images/Card1.png for example, then simply load the images via a loop
File images = new File("src/Images");
for(int i=0; i < cards.length; i++)
{
cards[i] = new ImageIcon(
ImageIO.read(
getClass().getResource("/images/Card" + i + ".png")));
deck.add(cards[i]);
}
Take a look at Reading/Loading an Image for more details about reading/loading images
Another solution might be to create a text file, which can be stored within the application context, which lists all the card names. You would use Class#getResource or Class#getResourceAsStream to load the file, read it's contents and load each image...
I'm creating a load button and want it to populate a 9x9 gridlayout content pane nested inside the CENTER panel of a border layout (main window). This method is located inside the PAGE_START section of the border layout. The question is how can I place the buttons in the Grid Layout of the CENTER section from here?
//Load Button
JButton load = new JButton("Load");
load.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent a) {
//Dialog Box To Locate The Puzzle
SudokuPuzzle puzzle;
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Text Files", "txt");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(SudukoGUI.this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
String fileLocation = chooser.getSelectedFile().getName();
Scanner file = new Scanner(fileLocation);
puzzle = new SudokuPuzzle(file, file);
//Load Puzzle To Model and draw it
try {
gridView = new JButton[9][9];
int[][] viewArray = puzzle.getArray();
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
gridView[row][col] = new JButton(String.valueOf(viewArray[row][col]));
***************THE NEXT LINE REPRESENTS MY PROBLEM***************
this.getContentPane().board.add(gridView[row][col]);
}
}
This is in the constructor
JPanel board = new JPanel();
board.setLayout (new GridLayout (9,9));
board.setPreferredSize(new Dimension(400,400));
this.getContentPane().add(board, BorderLayout.CENTER);
This
this.getContentPane().board.add(gridView[row][col]);
Does not make any sense. You added board to the content pane in your constructor, but this does not mean that board is now a field of the content pane. So
getContentPane().board
Should fail to compile.
You should probably make board a field of your class, rather than declaring it a local variable in your constructor. Then you will able to refer to board throughout the body of your class.
Basic example:
public class Example
{
private JPanel board;
public Example()
{
board = new JPanel();
getContentPane().add(board);
//assuming above code takes place in the constructor
JButton load = new JButton("load");
load.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
...lots of code
//as board is no longer a local variable this will compile
board.add(gridView[row][col]);
}
}
}
}
Note that you probably want to add load to your frame at some point.
First of all declare board as final variable using:
final JPanel board = new JPanel();
So that board could be accessed from anonymous inner class of ActionListener. Thereafter, change this line:
this.getContentPane().board.add(gridView[row][col]);
To
board.add(gridView[row][col]);
I'm a college student and this is my first time I have ever created a gui in Java. Right now I looked at this answer GUI in Java using Swing and followed the instructions and still nothing happens. Here is the code. I cut out all the irrelevant junk.
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Lab4Shell
{
// this holds the current game board
private char[][] gameBoard = new char[7][8];
private JButton[][] gameButtons = new JButton[7][8];
private ImageIcon red = new ImageIcon("Red.jpg");
private ImageIcon black = new ImageIcon("Black.jpg");
private ImageIcon empty = new ImageIcon("Empty.jpg");
private JPanel panel = new JPanel();
private int currentPlayer = 1;
private int numMoves = 0;
//Why do you want everything in constructor?
public Lab4Shell()
{
CreateWindow();
ResetGame();
// set layout
// loop through buttons array creating buttons, registering event handlers and adding buttons to panel
// add panel to frame
// do other initialization of applet
}
public static void CreateWindow()
{
//Sets window title and create window object.
JFrame aWindow = new JFrame("Connect Four");
//Set window position and size
aWindow.setBounds(500,100,400,400);
//What close button does.
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Make window visible.
aWindow.setVisible(true);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Lab4Shell game = new Lab4Shell();
}
});
}
void ResetGame()
{
JLabel label = new JLabel();
label.setIcon(empty);
for(int r=0;r<gameBoard.length;r++)
{
java.util.Arrays.fill(gameBoard[r],0,gameBoard[r].length,'0');
//loop through board columns
for(int c=0;c<gameBoard[r].length;c++)
{
}
}
// loop through array setting char array back to ' ' and buttons array back to empty pic
// reset currentPlayer and numMoves variables
}
You have to add the created ImageIcons to the panel as Manos said, and being the images at the src folder of Eclipse project, do that:
java.net.URL url = getClass().getResource("red.JPEG");
ImageIcon red = new ImageIcon(url);
If the resources are embedded with the application (within in the jar), the you need to use Class#getResource to load them.
The preferred mechanism for loading images is through the ImageIO API. It supports more image formats (as well as providing a pluggable architecture) and guarantees an image that is ready to be displayed once the read method returns
BufferedImage redImage;
// ...
URL url = getClass().getResource("red.JPEG");
if (url != null) {
redImage = ImageIO.read(url);
} else {
throw new NullPointerException("Unable to locate red image resource");
}
You can try this
BufferedImage myPicture = ImageIO.read(new File("path-to-file"));
JLabel picLabel = new JLabel(new ImageIcon( myPicture ));
add( picLabel );
You've never adding anything to your frame - which is causing your problem. So in you createWindow method, you need to call:
aWindow.setContentPane(panel);
Then later on (like in your resetGame method), you'll add your content (like the JLabel) to the panel:
panel.add(empty);
Where it's added to your panel is determined by the LayoutManager of the panel (there are many of them - the default is BorderLayout)
Other helpful things:
Generally, when it makes sense, create/initialize your objects in the constructor and add/remove/update them in the runtime.
For troubleshooting, use the .setOpaque(true) and .setBackground(Color.blue) methods on what you want to see. If you don't see it then, either something is covering it up, or it was never added
Good luck.
I'm trying to add several JLabels to a JPanel along with mouse listeners using a loop. These JLabels are going to have mouse listeners so that they change their icon when clicked (Using label.setIcon()). However, I only want to have one "selected" at a time. So, I need them to know when another label is clicked so it knows to turn itself off before the new label gets selected. However, my problem is that because I'm adding these labels with a loop they all have the same MouseListener.
Can anyone teach me a simple way to accomplish this?
This is a short example, how you could implement it (please note, that I didn't use the icon, but change the label instead):
public class MouseListenerExample extends JFrame {
public static class MyMouseListener extends MouseAdapter {
private static final Collection<JLabel> labels = new ArrayList<JLabel>();
private final JFrame frame;
public MyMouseListener(JFrame frame, JLabel label) {
this.frame = frame;
labels.add(label);
}
#Override
public void mouseClicked(MouseEvent e) {
for (JLabel label : labels) {
String text = label.getText();
if (text.startsWith("X ")) {
label.setText(text.substring(2));
}
}
JLabel currentLabel = (JLabel) e.getComponent();
currentLabel.setText("X " + currentLabel.getText());
}
}
public MouseListenerExample() {
super("MouseListener Example");
Container c = getContentPane();
c.setLayout(new FlowLayout());
for (int i = 0; i < 10; i++) {
JLabel jLabel = new JLabel("Label " + i);
c.add(jLabel);
jLabel.addMouseListener(new MyMouseListener(this, jLabel));
}
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new MouseListenerExample();
}
}
The main idea is, that you create a new MouseListener for each label, but keep a list of labels outside of each listener's scope (in this example I just use a static variable, but you could also have a field containing the list of labels in the frame.