So I'm desinging an application for offline quiz systems. Currently I'm working on the screen that is visible for the participants (only question, maybe possible answers and a media element).
This screen contains a slide (derived from JPanel) the screen itself is a JFrame. I have to use the JPanel in another JFrame. In the JPanel of the slide is another JPanel for displaying media. I succeeded to display an image in the JPanel. But the application also has to display video and audio. I use VLCj to realize this in my application. Here is the code of the JFrame of the SlideView.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
/**
* Created by bram on 30/03/17.
*/
public class SlideView
{
private SlidePanel slidePanel;
private JFrame frame;
public SlideView(){
slidePanel = new SlidePanel();
frame = new JFrame("SlideView");
frame.setLayout(new BorderLayout());
Dimension dim = new Dimension();
dim.setSize(800,450);
frame.setMinimumSize(dim);
frame.add(slidePanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.addComponentListener(new ComponentListener() {
public void componentMoved(ComponentEvent e){}
public void componentHidden(ComponentEvent e){}
public void componentShown(ComponentEvent e){}
public void componentResized(ComponentEvent e)
{
frame.add(slidePanel,BorderLayout.CENTER);
}
});
}
/**
* Display the information of the slide
* #pre slide has to be initialized
* #pre the slideview is initialized
* #param slide the slide that has to be displayed
* #post the slide will be displayed
*/
public void setSlide(Slide slide)
{
slidePanel.initializeSlide(slide);
}
/**
* Set the slide panel
* #param panel
*/
public void setSlidePanel(SlidePanel panel)
{
frame.remove(slidePanel);
slidePanel = panel;
frame.add(slidePanel);
}
/**
* Get the slide panel
* #return the slide panel
*/
public SlidePanel getSlidePanel()
{
return slidePanel;
}
}
And here is the code of the panel that contains the information of the slide:
import javax.swing.*;
import java.awt.*;
import java.net.URL;
/**
* Created by bram on 30/03/17.
*/
public class SlidePanel extends JPanel {
private ImageIcon bgImage;
private JLabel title, body;
private Slide slide;
private MediaView media;
public SlidePanel()
{
bgImage = new ImageIcon("/home/bram/Documenten/School/3 BA/PSOPV/LOCAL/src/Slides/slide_background.jpg");
this.setSize(800,450);
createComponents();
}
/**
* Get the media view for controlling it
*/
public MediaView getMediaView()
{
return media;
}
/**
* Initialize the slide
*/
public void initializeSlide(Slide slide)
{
this.slide = slide;
title.setText(slide.getTitle());
body.setText(slide.getBodyText());
media.setFile(slide.getMediaFile());
resizeComponents();
}
#Override
/**
* Actions that will be executed when the window is resized
*/
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw the background image.
g.drawImage(getResizedBackground().getImage(), 0, 0, this);
resizeComponents();
}
/**
* Resize the different components to the dimensions of the frame
*/
private void resizeComponents()
{
/*Calculate the growing factor of the screen (minimum size is 800*450)*/
float growFactor = (float) this.getWidth() / 800f;
/*Scale the title label*/
title.setFont(new Font("SansSerif", Font.BOLD, (int)(40*growFactor)));
title.setBounds((int)(20 * growFactor), (int)(20*growFactor),this.getWidth(), (int)(50 * growFactor));
/*Scale the body section*/
body.setFont(new Font("SansSerif", Font.PLAIN,(int)(25*growFactor)));
body.setBounds((int)(50*growFactor),(int)(0.25f*this.getHeight()),(int)((this.getWidth()-50*growFactor) * 0.5f), (int)(0.75f*this.getHeight()-20));
/*Scale the media section*/
media.setBounds((int)(this.getWidth()*0.5),(int)(this.getHeight()*0.30), (int)(this.getWidth() * 0.40),(int)(this.getHeight()*0.60-20));
}
/**
* Create the title label of the slide
*/
private void createTitle()
{
title = new JLabel("",SwingConstants.LEFT);
title.setForeground(Color.WHITE);
this.add(title);
}
/**
* Create the body of the slide
*/
private void createBody()
{
body = new JLabel("");
this.add(body);
}
/**
* Create the media section
*/
private void createMedia()
{
media = new MediaView();
media.setSize(100,100);
this.add(media);
}
/**
* Create the gui components for displaying a slide
*/
private void createComponents()
{
createTitle();
createBody();
createMedia();
}
/**
* Scale the background to the height and width of the panel
* #return the resized background
*/
private ImageIcon getResizedBackground()
{
Image img = bgImage.getImage();
img = img.getScaledInstance(this.getWidth(),this.getHeight(), Image.SCALE_DEFAULT);
return new ImageIcon(img);
}
}
And finally here is the JPanel that has to display the media:
import com.sun.jna.NativeLibrary;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.videosurface.CanvasVideoSurface;
import uk.co.caprica.vlcj.player.media.Media;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
/**
* Created by bram on 31/03/17.
*/
public class MediaView extends JPanel
{
private MediaFile file;
//Label for displaying a picture
private JLabel picture;
//Media player for video and audio
private EmbeddedMediaPlayerComponent mediaPlayer;
private int width,height;
private static final String NATIVE_LIBRARY_SEARCH_PATH = "lib";
/**
* Default constructor for the mediaview class
*/
public MediaView()
{
setOpaque(false);
setLayout(new GridBagLayout());
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), NATIVE_LIBRARY_SEARCH_PATH);
this.width = getWidth();
this.height = getHeight();
}
/**
* Add the appropriate components to the panel
*/
private void addComponents()
{
if(file.getFileType() == MediaFile.FileType.PICTURE)
{
picture = new JLabel();
this.add(picture);
}
if(file.getFileType() == MediaFile.FileType.VIDEO)
{
mediaPlayer = new EmbeddedMediaPlayerComponent();
setLayout(new BorderLayout());
add(mediaPlayer, BorderLayout.CENTER);
mediaPlayer.setSize(this.getWidth(),this.getHeight());
}
}
/**
* Set the media file to be displayed
* #pre the media file is initialized
* #param file the file that has to be displayed
*/
public void setFile(MediaFile file)
{
this.file = file;
addComponents();
generateView();
}
#Override
/**
* Actions that will be executed when the window is resized
*/
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(this.height != getHeight() || this.width != getWidth())
{
generateView();
height = getHeight();
width = getWidth();
}
}
/**
* Generate the view of the file
*/
private void generateView()
{
if(file == null)
return;
if(file.getFileType() == MediaFile.FileType.PICTURE)
generateImage();
if(file.getFileType() == MediaFile.FileType.VIDEO)
generateVideo();
if(file.getFileType() == MediaFile.FileType.AUDIO)
generateAudio();
}
/**
* Generate the view of an audio file
*/
private void generateAudio()
{
}
/**
* Generate the view of a video
*/
public void generateVideo()
{
//Resize canvas
//Load native library of VLC
}
public void playMedia()
{
mediaPlayer.getMediaPlayer().playMedia(file.getPath());
}
/**
* Generate the view of an image
*/
private void generateImage()
{
/*Get the image by path*/
ImageIcon image = new ImageIcon(file.getPath());
/*Scale the image*/
Image img = image.getImage();
if(image.getIconHeight() > image.getIconWidth()) {
float growFactor = (float) this.getHeight() / (float) image.getIconHeight();
int width = (int) (image.getIconWidth() * growFactor);
img = img.getScaledInstance(width, this.getHeight(), Image.SCALE_DEFAULT);
} else {
float growFactor = (float) this.getWidth() / (float) image.getIconWidth();
int height = (int) (image.getIconHeight() * growFactor);
img = img.getScaledInstance(this.getWidth(),height,Image.SCALE_DEFAULT);
}
ImageIcon pic = new ImageIcon(img);
/*Set image as label icon*/
picture.setIcon(pic);
/*Set the bounds of the label*/
int xCoordinate = (this.getWidth() - pic.getIconWidth())/2;
int yCoordinate = (this.getHeight() - pic.getIconHeight())/2;
picture.setHorizontalAlignment(JLabel.CENTER);
picture.setVerticalAlignment(JLabel.CENTER);
picture.setBounds(xCoordinate,yCoordinate,picture.getWidth(),picture.getHeight());
}
}
But the video won't display (the video is a MP4 format). I tried several things (the above is the best result) does anyone can help me?
Related
I'm trying to build a web browser in java swing where i added new tab option by adding JTabbedPane. But i want to update my current tab title when i browse another web page or urls etc. I used WebView and WebEngine as html parser. I tried to update title name using WebEngine.getTitle() it didn't work.
Here is my constructor:
public class Hello extends JFrame {
private JButton backButton = new JButton();
private JButton newPage;
private JButton forwardButton = new JButton();
private JFXPanel jfxPanel = new JFXPanel();
private JTextField locationTextField = new JTextField(100);
private JPanel fPane = new JPanel(new BorderLayout());
private JPanel totalPane = new JPanel(new BorderLayout());
private WebEngine engine;
JPanel buttonPanel = new JPanel(new BorderLayout());
public ArrayList<String> pageList = new ArrayList<>();
public ArrayList<String> historyList = new ArrayList<>();
static int value = 0;
static int inI = 0;
public ArrayList<String> title = new ArrayList<>();
public ArrayList<String> titleUrl = new ArrayList<>();
Hashtable<String, String> table;
History hist;
final JTabbedPane tb;
private GraphicsDevice device;
private JFrame frame;
public Hello() {
currentScene();
table = new Hashtable<>();
setResizable(true);
setTitle("Pooh");
ImageIcon img = new ImageIcon(Hello.class.getResource("/Panda-icon.png"));
setIconImage(img.getImage());
JPanel buttonPanel1 = new JPanel();
buttonPanel1.setBackground(Color.decode("#330300"));
backButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
BorderFactory.createRaisedBevelBorder();
actionBack();
System.out.println(value + " " + pageList.size() + " back");
}
});
backButton.setEnabled(true);
backButton.setBorderPainted(false);
buttonPanel1.add(backButton);
forwardButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (pageList.size() > value) {
value++;
}
System.out.println(value + "forwad");
actionForward();
}
});
forwardButton.setEnabled(true);
locationTextField.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
value++;
String tUrl = toURL(locationTextField.getText());
actionGo(locationTextField.getText());
}
}
});
locationTextField.setDragEnabled(true);
buttonPanel1.add(locationTextField, BorderLayout.EAST);
JPanel buttonPanel2 = new JPanel(new BorderLayout(5, 5));
buttonPanel2.setBackground(Color.decode("#330300"));
newPage = new JButton();
newPage.setIcon(new ImageIcon(Hello.class.getResource("/Plus.png")));
newPage.setPreferredSize(new Dimension(30,30));
newPage.setBorderPainted(false);
newPage.setBackground(Color.decode("#330300"));
newPage.setToolTipText("New Page");
newPage.setEnabled(true);
buttonPanel2.add(newPage,BorderLayout.CENTER);
buttonPanel.setBackground(Color.decode("#330300"));
buttonPanel.add(buttonPanel1, BorderLayout.WEST);
buttonPanel.add(buttonPanel2, BorderLayout.EAST);
JPanel lblBar = new JPanel(new BorderLayout());
lblBar.setPreferredSize(new Dimension(50,10));
JPanel jp = new JPanel();
jp.setLayout(new BorderLayout());
UIManager.put("TabbedPane.background",Color.decode("#330300"));
tb = new JTabbedPane();
tb.setUI(new CustomTabbedPaneUI());
tb.setForeground(Color.decode("#330300"));
**//creating initial tab with default name "Google" which i want to change when new urls are clicked**
tb.addTab("Google",fPane);
jp.add(new JLayer<JTabbedPane>(tb));
**//creating new tabs when button is clicked**
newPage.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
tb.addTab("New Tab",new JPanel());
**//a method which takes index of tabbed pane and returns a tabbed pane**
initTabComponent(inI+1);
inI++;
}
});
tb.setOpaque(true);
fPane.add(jfxPanel,BorderLayout.CENTER);
totalPane.add(buttonPanel, BorderLayout.NORTH);
totalPane.add(jp, BorderLayout.CENTER);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setLayout(new BorderLayout());
getContentPane().add(totalPane,BorderLayout.CENTER);
getContentPane().add(lblStatus,BorderLayout.PAGE_END);
setPreferredSize(new Dimension(1024, 600));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
}
Here is my currentScene() method:
private void currentScene() {
Platform.runLater(new Runnable() {
#Override
public void run() {
WebView view = new WebView();
engine = view.getEngine();
engine.createPopupHandlerProperty();
engine.titleProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, final String newValue) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Hello.this.setTitle(newValue);
if (newValue != null) {
table.put(newValue, tUrl);
title.add(newValue);
historyList.add(newValue);
pageList.add(tUrl);
}
}
});
}
});
engine.setOnStatusChanged(new EventHandler<WebEvent<String>>() {
#Override
public void handle(final WebEvent<String> event) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
lblStatus.setText(event.getData());
}
});
}
});
engine.locationProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> ov, String oldValue, final String newValue) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
titleUrl.add(newValue);
locationTextField.setText(newValue);
}
});
}
});
engine.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, final Number newValue) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
progressBar.setValue(newValue.intValue());
}
});
}
});
engine.getLoadWorker()
.exceptionProperty()
.addListener(new ChangeListener<Throwable>() {
public void changed(ObservableValue<? extends Throwable> o, Throwable old, final Throwable value) {
if (engine.getLoadWorker().getState() == FAILED) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JOptionPane.showMessageDialog(
fPane,
(value != null)
? engine.getLocation() + "\n" + value.getMessage()
: engine.getLocation() + "\nUnexpected error.",
"Loading error...",
JOptionPane.ERROR_MESSAGE);
}
});
}
}
});
jfxPanel.setScene(new Scene(view));
}
});
}
You will want to call setTitleAt(...) on the JTabbedPane to change the title of the tab.
I prefer CloseableTabbedPane . It has methid addTab with tab title and icon
You can download it here https://github.com/dimensionv/closeabletabbedpane
package de.dimensionv.java.gui.swing.panels;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.Icon;
/**
* Draws an icon representing an "X" in a box. The constructor accepts an icon, which will be placed next (right) to the
* 'X' icon drawn by this class. If no extra icon is needed, the empty default constructor can be used, or provide
* "null" as a value for the icon-object.
*
* #author mjoellnir
* #version 1.0
*/
public class CloseTabIcon implements Icon {
private int xPos;
private int yPos;
private int width = 16;
private int height = 16;
private final int offsetFrame = 2;
private final int offsetCross1 = 3;
private final int offsetCross2 = 4;
private Icon extraIcon = null;
/**
* Creates new "X" Icon.
*/
public CloseTabIcon() {
}
/**
* Creates new "X" Icon with an extra icon next to it.
*
* #param fileIcon the Icon-object to be placed next to this icon.
* #see javax.swing.Icon
*/
public CloseTabIcon(Icon fileIcon) {
extraIcon = fileIcon;
}
#Override
public void paintIcon(Component component, Graphics graphics, int x, int y) {
setXPos(x);
setYPos(y);
Color col = graphics.getColor();
graphics.setColor(Color.black);
// prepare coordinates for the frame...
int frameTop = y + offsetFrame;
int frameBottom = y + (height - offsetFrame);
int frameLeft = x + offsetFrame;
int frameRight = x + (width - offsetFrame);
// top line of rectangle-frame...
graphics.drawLine(frameLeft + 2, frameTop, frameRight - 2, frameTop);
// bottom line of rectangle-frame...
graphics.drawLine(frameLeft + 2, frameBottom, frameRight - 2, frameBottom);
// left line of rectangle-frame...
graphics.drawLine(frameLeft, frameTop + 2, frameLeft, frameBottom - 2);
// right line of rectangle-frame...
graphics.drawLine(frameRight, frameTop + 2, frameRight, frameBottom - 2);
// rounding
graphics.drawLine(frameLeft + 1, frameTop + 1, frameLeft + 1, frameTop + 1);
graphics.drawLine(frameRight - 1, frameTop + 1, frameRight - 1, frameTop + 1);
graphics.drawLine(frameLeft + 1, frameBottom - 1, frameLeft + 1, frameBottom - 1);
graphics.drawLine(frameRight - 1, frameBottom - 1, frameRight - 1, frameBottom - 1);
// prepare coordinates for the "X"
int crossTop1 = frameTop + offsetCross1;
int crossBottom1 = frameBottom - offsetCross1;
int crossTop2 = frameTop + offsetCross2;
int crossBottom2 = frameBottom - offsetCross2;
int crossRight1 = frameRight - offsetCross1;
int crossLeft1 = frameLeft + offsetCross1;
int crossRight2 = frameRight - offsetCross2;
int crossLeft2 = frameLeft + offsetCross2;
// first diagonal of "X": top left to bottom right...
graphics.drawLine(crossLeft1, crossTop1, crossRight1, crossBottom1);
graphics.drawLine(crossLeft1, crossTop2, crossRight2, crossBottom1);
graphics.drawLine(crossLeft2, crossTop1, crossRight1, crossBottom2);
// second diagonal of "X": top right to bottom left...
graphics.drawLine(crossRight1, crossTop1, crossLeft1, crossBottom1);
graphics.drawLine(crossRight1, crossTop2, crossLeft2, crossBottom1);
graphics.drawLine(crossRight2, crossTop1, crossLeft1, crossBottom2);
graphics.setColor(col);
if (extraIcon != null) {
extraIcon.paintIcon(component, graphics, x + getWidth(), y + 2);
}
}
#Override
public int getIconWidth() {
return getWidth() + (extraIcon != null ? extraIcon.getIconWidth() : 0);
}
#Override
public int getIconHeight() {
return getHeight();
}
/**
* Returns the bounding rectangle of this icon.
*
* #return the bounding rectangle of this icon.
* #see java.awt.Rectangle
*/
public Rectangle getBounds() {
return new Rectangle(getXPos(), getYPos(), getWidth(), getHeight());
}
/**
* Returns the x-coordinate of the position of this icon.
*
* #return the x-coordinate of the position of this icon.
*/
public int getXPos() {
return xPos;
}
/**
* Returns the y-coordinate of the position of this icon.
*
* #return the y-coordinate of the position of this icon.
*/
public int getYPos() {
return yPos;
}
/**
* Returns the width of this icon.
*
* #return the width of this icon.
*/
public int getWidth() {
return width;
}
/**
* Returns the height of this icon.
*
* #return the height of this icon.
*/
public int getHeight() {
return height;
}
/**
* Returns the extra-icon, which is to be displayed next to this icon. Might be null.
*
* #return the extra-icon.
*/
public Icon getExtraIcon() {
return extraIcon;
}
/**
* Sets the x-coordinate of the position of this icon.
*
* #param xPos the x-coordinate of the position of this icon.
*/
protected void setXPos(int xPos) {
this.xPos = xPos;
}
/**
* Sets the y-coordinate of the position of this icon.
*
* #param yPos the y-coordinate of the position of this icon.
*/
protected void setYPos(int yPos) {
this.yPos = yPos;
}
/**
* Sets the width of this icon.
* <p>
* This method should be called only within the constructor-methods.</p>
*
* #param width the width of this icon.
*/
protected void setWidth(int width) {
this.width = width;
}
/**
* Sets the height of this icon.
* <p>
* This method should be called only within the constructor-methods.</p>
*
* #param height the height of this icon.
*/
protected void setHeight(int height) {
this.height = height;
}
/**
* Sets the extra-icon to be displayed next to this icon.
* <p>
* This method should be called only within the constructor-methods.</p>
*
* #param extraIcon the extra icon to display.
*/
protected void setExtraIcon(Icon extraIcon) {
this.extraIcon = extraIcon;
}
}
package de.dimensionv.java.gui.swing.panels;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.Icon;
import javax.swing.JTabbedPane;
/**
* A JTabbedPane that can have a close-icon ('X') on each tab.
*
* <p>
* Since it is derived from JTabbedPane directly, it is used in exactly the same manner as the JTabbedPane. By default,
* it even behaves equally, i.e. it does not add the close-icon, thus disabling the closing-capabilities completely for
* a tab. To enable the closing-capabilities of a tab, add a boolean value (true) the the addTab-method-call.</p>
*
* <p>
* To have an additional extra icon on each tab (e.g. showing the file type), use the method addTab(String, Component,
* Icon) or addTab(String, Component, Icon, boolean). The first variant goes without closing-capabilities, while the
* second, if the boolean is set to true, comes with closing-capabilities.</p>
*
* <p>
* Clicking the 'X', of course, closes the tab. If you like to perform action, <b>after</b> the tab has already been
* closed, implement an event-listener to capture the ComponentRemoved-event. The removed tab can be retrieved by
* calling java.awt.event.ContainerEvent.getChild(), which is the event the listener will receive.</p>
*
* #author mjoellnir
*/
public class CloseableTabbedPane extends JTabbedPane implements MouseListener {
/**
* Creates a new instance of ClosableTabbedPane
*/
public CloseableTabbedPane() {
super();
initializeMouseListener();
}
/**
* Appends a tab without closing-capabilities, just as the standard JTabbedPane would do.
*
* #see javax.swing.JTabbedPane#addTab(String title, Component component) addTab
*/
#Override
public void addTab(String title, Component component) {
this.addTab(title, component, null, false);
}
/**
* Appends a tab with or without closing-capabilities, depending on the flag isClosable. If isClosable is true, a
* close-icon ('X') is displayed left of the title.
*
* #param title Title of this tab.
* #param component Contents of this tab.
* #param isClosable en-/disable closing-capabilities
* #see javax.swing.JTabbedPane#addTab(String title, Component component) addTab
*/
public void addTab(String title, Component component, boolean isClosable) {
this.addTab(title, component, null, isClosable);
}
/**
* Appends a tab with or without closing-capabilities, depending on the flag isClosable. If isClosable is true, a
* close-icon ('X') is displayed left of the title. If extraIcon is not null, it will be displayed between the closing
* icon (if present) and the tab's title. The extraIcon will be displayed indepently of the closing-icon.
*
* #param title Title of this tab.
* #param component Contents of this tab.
* #param extraIcon Extra icon to be displayed.
* #param isClosable en-/disable closing-capabilities
* #see javax.swing.JTabbedPane#addTab(String title, Component component) addTab
*/
public void addTab(String title, Component component, Icon extraIcon, boolean isClosable) {
if (isClosable) {
super.addTab(title, new CloseTabIcon(extraIcon), component);
} else {
if (extraIcon != null) {
super.addTab(title, extraIcon, component);
} else {
super.addTab(title, component);
}
}
}
#Override
public void mouseClicked(MouseEvent evt) {
int tabIndex = getUI().tabForCoordinate(this, evt.getX(), evt.getY());
if (tabIndex < 0) {
return;
}
Icon icon = getIconAt(tabIndex);
if ((icon == null) || !(icon instanceof CloseTabIcon)) {
// This tab is not intended to be closeable.
return;
}
Rectangle rect = ((CloseTabIcon) icon).getBounds();
if (rect.contains(evt.getX(), evt.getY())) {
//the tab is being closed
this.removeTabAt(tabIndex);
}
}
#Override
public void mouseEntered(MouseEvent evt) {
}
#Override
public void mouseExited(MouseEvent evt) {
}
#Override
public void mousePressed(MouseEvent evt) {
}
#Override
public void mouseReleased(MouseEvent evt) {
}
private void initializeMouseListener() {
addMouseListener(this);
}
}
Found this sample code which should produce a drawn line after clicking, but does not show anything or works. Assume all import statements are correct, code gives no errors and I have no idea why it would not work. The line color is red while the background is white so it should show clearly if it works. The mouse listener seems to be correct as well. Any reason why this code will not work?
public class PathPanel extends JPanel {
/**
* The panel width.
*/
public static final int WIDTH = 400;
/**
* The panel height.
*/
public static final int HEIGHT = 400;
/**
* The background color of the panel.
*/
public static final Color BACKGROUND_COLOR = Color.WHITE;
/**
* The color to paint with.
*/
public static final Color FOREGROUND_COLOR = Color.RED;
/**
* The line width.
*/
public static final int LINE_WIDTH = 8;
// Instance Fields
/**
*
*/
private static final long serialVersionUID = -3644129903653409515L;
/**
* The path being created.
*/
private final Path2D myPath;
// OR you could use Path2D.Double instead of GeneralPath
// Constructor
/**
* Constructs a new general path panel.
*/
public PathPanel() {
super();
myPath = new GeneralPath();
myPath.setWindingRule(GeneralPath.WIND_EVEN_ODD);
//myPath = new Path2D.Double();
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(BACKGROUND_COLOR);
addMouseListener(new MyMouseListener());
}
/**
* Paints the current path.
*
* #param theGraphics The graphics context to use for painting.
*/
#Override
public void paintComponent(final Graphics theGraphics) {
super.paintComponent(theGraphics);
final Graphics2D g2d = (Graphics2D) theGraphics;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(FOREGROUND_COLOR);
g2d.setStroke(new BasicStroke(LINE_WIDTH));
g2d.draw(myPath);
}
// Main Method
/**
* Creates and displays a GeneralPathPanel.
*
* #param theArgs Command line arguments (ignored).
*/
public static void main(final String... theArgs) {
final PathPanel panel = new PathPanel();
final JFrame frame = new JFrame("GeneralPathPanel Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
// Inner Class
/**
* Listens for mouse clicks, to draw on our panel.
*/
private class MyMouseListener extends MouseAdapter {
/**
* Handles a click event.
*
* #param theEvent The event.
*/
#Override
public void mouseClicked(final MouseEvent theEvent) {
if (myPath.getCurrentPoint() == null) {
myPath.moveTo(theEvent.getX(), theEvent.getY());
} else if (theEvent.getClickCount() == 2) {
myPath.closePath();
} else {
myPath.lineTo(theEvent.getX(), theEvent.getY());
}
repaint();
}
}
}
The Sample Code you posted works fine for me. Have you tried to add a System.out.println() in the mouseClicked(final MouseEvent theEvent) Method to check if it is actually called? If it is not called, you could try to change it to mouseReleased.
The imports I used:
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
im using the Canvas class to make a screensaver as a schoolproject.
But the window generated by Canvas doesnt show my objects on it (current time)
until i minimize it an resize it again. After that all things works fine.
so what is wrong?
thank you for coming answers!
with kind regards
leon
those are the classes, i peronally think that the problem is in the class Start or BufferedCanvas
import java.awt.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Start
{
int fensterX = 900;
int fensterY = 700;
Farbengenerator fg = new Farbengenerator();
BufferedCanvas c =newBufferedCanvas("Bild",fensterX,fensterY);
Zeit z = new Zeit();
SchriftParameter sp = new SchriftParameter();
public void zeichneText(){
double x = 100;
double y = 100;
double fy =0.01;
double fx =0.02;
int red=0;
int green=0;
int blue=0;
double colourGrowRate=0.05;
String uhr;
c.setFont(sp.setzteSchrift());
c.setForegroundColour(Color.BLACK);
c.setBackgroundColour(Color.WHITE);
for(int i=0;i<100;i++){
c.drawString("Starting...",(int)x,(int)y);
c.updateAndShow();
try{Thread.sleep(50);}
catch(Exception e){};
c.updateAndShow();
}
CreateButton d = new CreateButton();
d.run();
while(true) {
c.erase();
uhr = z.erstelleZeit();
c.drawString(uhr,(int)x,(int)y);
if((int)x >fensterX-93 || (int)x <5){
fx = fx * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)y > fensterY-1 || (int)y < 46){
fy = fy * (-1);
red=fg.gibROT();
green=fg.gibGRUEN();
blue=fg.gibBLAU();
Color colour = new Color(red,green,blue);
c.setForegroundColour(colour);
}
if((int)colourGrowRate>=1){
fg.generiereFarbe();
colourGrowRate = 0.05;
}
colourGrowRate=colourGrowRate+colourGrowRate;
x = x + fx;
y = y + fy;
c.updateAndShow();
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;
public class BufferedCanvas
{
private JFrame frame;
private CanvasPane canvas;
private Graphics2D graphic;
private Color backgroundColour;
private Image canvasImage;
BufferStrategy buff;
/**
* Create a BufferedCanvas with default height,
width and background colour
* (300, 300, white).
* #param title title to appear in Canvas Frame
*/
public BufferedCanvas(String title)
{
this(title, 300, 300, Color.white);
}
/**
* Create a BufferedCanvas with default background colour (white).
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
*/
public BufferedCanvas(String title, int width, int height)
{
this(title, width, height, Color.white);
}
/**
* Create a BufferedCanvas.
* #param title title to appear in Canvas Frame
* #param width the desired width for the canvas
* #param height the desired height for the canvas
* #param bgClour the desired background colour of the canvas
*/
public BufferedCanvas(String title, int width, int height, Color bgColour)
{
frame = new JFrame();
canvas = new CanvasPane();
frame.setContentPane(canvas);
frame.setTitle(title);
canvas.setPreferredSize(new Dimension(width, height));
backgroundColour = bgColour;
frame.pack();
frame.createBufferStrategy(2);
buff = frame.getBufferStrategy();
graphic = (Graphics2D)buff.getDrawGraphics();
setVisible(true);
}
/**
* Set the canvas visibility and brings canvas to the front of screen
* when made visible. This method can also be used to bring an already
* visible canvas to the front of other windows.
* #param visible boolean value representing the desired visibility of
* the canvas (true or false)
*/
public void setVisible(boolean visible)
{
if(graphic == null) {
// first time: instantiate the offscreen image and fill it with
// the background colour
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColour);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(true);
}
/**
* Update the canvas and show the new image.
*/
public void updateAndShow(){
buff.show();
}
/**
* Provide information on visibility of the Canvas.
* #return true if canvas is visible, false otherwise
*/
public boolean isVisible()
{
return frame.isVisible();
}
/**
* Draw a given shape onto the canvas.
* #param shape the shape object to be drawn on the canvas
*/
public void draw(Shape shape)
{
graphic.draw(shape);
//canvas.repaint();
}
/**
* Fill the internal dimensions of a given shape with the current
* foreground colour of the canvas.
* #param shape the shape object to be filled
*/
public void fill(Shape shape)
{
graphic.fill(shape);
//canvas.repaint();
}
/**
* Erase the whole canvas.
*/
public void erase()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erase a given shape's interior on the screen.
* #param shape the shape object to be erased
*/
public void erase(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.fill(shape); // erase by filling background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Erases a given shape's outline on the screen.
* #param shape the shape object to be erased
*/
public void eraseOutline(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.draw(shape); // erase by drawing background colour
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws an image onto the canvas.
* #param image the Image object to be displayed
* #param x x co-ordinate for Image placement
* #param y y co-ordinate for Image placement
* #return returns boolean value representing whether the image was
* completely loaded
*/
public boolean drawImage(Image image, int x, int y)
{
boolean result = graphic.drawImage(image, x, y, null);
//canvas.repaint();
return result;
}
/**
* Draws a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void drawString(String text, int x, int y)
{
graphic.drawString(text, x, y);
//canvas.repaint();
}
/**
* Erases a String on the Canvas.
* #param text the String to be displayed
* #param x x co-ordinate for text placement
* #param y y co-ordinate for text placement
*/
public void eraseString(String text, int x, int y)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColour);
graphic.drawString(text, x, y);
graphic.setColor(original);
//canvas.repaint();
}
/**
* Draws a line on the Canvas.
* #param x1 x co-ordinate of start of line
* #param y1 y co-ordinate of start of line
* #param x2 x co-ordinate of end of line
* #param y2 y co-ordinate of end of line
*/
public void drawLine(int x1, int y1, int x2, int y2)
{
graphic.drawLine(x1, y1, x2, y2);
//canvas.repaint();
}
/**
* Draws a dot/pixel on the Canvas.
* #param x x co-ordinate of dot
* #param y y co-ordinate of dot
*/
public void drawDot(int x, int y)
{
graphic.drawLine(x, y, x, y);
//canvas.repaint();
}
/**
* Sets the foreground colour of the Canvas.
* #param newColour the new colour for the foreground of the Canvas
*/
public void setForegroundColour(Color newColour)
{
graphic.setColor(newColour);
}
/**
* Returns the current colour of the foreground.
* #return the colour of the foreground of the Canvas
*/
public Color getForegroundColour()
{
return graphic.getColor();
}
/**
* Sets the background colour of the Canvas.
* #param newColour the new colour for the background of the Canvas
*/
public void setBackgroundColour(Color newColour)
{
backgroundColour = newColour;
graphic.setBackground(newColour);
}
/**
* Returns the current colour of the background
* #return the colour of the background of the Canvas
*/
public Color getBackgroundColour()
{
return backgroundColour;
}
/**
* changes the current Font used on the Canvas
* #param newFont new font to be used for String output
*/
public void setFont(Font newFont)
{
graphic.setFont(newFont);
}
/**
* Returns the current font of the canvas.
* #return the font currently in use
**/
public Font getFont()
{
return graphic.getFont();
}
/**
* Sets the size of the canvas.
* #param width new width
* #param height new height
*/
public void setSize(int width, int height)
{
canvas.setPreferredSize(new Dimension(width, height));
Image oldImage = canvasImage;
canvasImage = canvas.createImage(width, height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.drawImage(oldImage, 0, 0, null);
frame.pack();
}
/**
* Returns the size of the canvas.
* #return The current dimension of the canvas
*/
public Dimension getSize()
{
return canvas.getSize();
}
/**
* Waits for a specified number of milliseconds before finishing.
* This provides an easy way to specify a small delay which can be
* used when producing animations.
* #param milliseconds the number
*/
public void wait(int milliseconds)
{
try
{
Thread.sleep(milliseconds);
}
catch (Exception e)
{
// ignoring exception at the moment
}
}
/************************************************************************
* Nested class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class CreateButton extends JFrame implements ActionListener{
public void run() {
createAndShowGUI();
}
public CreateButton() {
// set layout for the frame
this.getContentPane().setLayout(new FlowLayout());
JButton button1 = new JButton();
button1.setText("closeApp");
//set actionlisteners for the buttons
button1.addActionListener(this);
// define a custom short action command for the button
button1.setActionCommand("closeApp");
// add buttons to frame
add(button1);
}
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new CreateButton();
//Display the window.
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent ae) {
String action = ae.getActionCommand();
if (action.equals("closeApp")) {
System.exit(1);
}
}
}
import java.awt.*;
public class SchriftParameter
{
public Font setzteSchrift(){
Font f = new Font("Fixed",1,24);
return (f);
}
}
public class Farbengenerator
{
int r=0;
int g=0;
int b=0;
public void generiereFarbe(){
if (r<255&&g==0&&b==0){
r++;
}
else if (r==255&&g<255&&b==0){
g++;
}
else if (r>0&&g==255&&b==0){
r= r-1;
}
else if (r==0&&g==255&&b<255){
b++;
}
else if (r==0&&g>0&&b==255){
g=g-1;
}
else if (r<255&&g==0&&b==255){
r++;
}
else if (r==255&&g==0&&b>0){
b=b-1;
}
}
public int gibROT () {
return(r);
}
public int gibGRUEN () {
return(g);
}
public int gibBLAU () {
return(b);
}
}
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Zeit
{
public String erstelleZeit(){
DateFormat df = new SimpleDateFormat("HH:mm:ss");
Date d = new Date();
String uhr = df.format(d);
return (uhr);
}
}
I'm very new to IDEA, and I wonder why my Custom Component can't be added to the GUI. I created a new project and added a new GUI and a new class which is a Component.
Here's the code for the Component:
package comps;
import javax.swing.*;
/**
* Created by danielmartin1 on 25.03.15.
*/
public class TestComp extends JLabel {
}
I'm using OSX Yosemite, with the JDK 1.8
Hope anyone can help me.
Using the custom bundled IDEA helped. Now i can add any Custom Component the GUI.
But there are now some other problems:
First, the component doesn't look as it should in the form editor (it looks like a combobox),
and Second: My program crashes when trying to run if the layout is set to GridlayoutManager(IntelliJ). With Borderlayout selected, it is running and my component is shown (only at runtime) correctly.
So here is the code for my component:
package gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class CustomTracker extends JComponent implements MouseListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private boolean isSelected = false;
public String getText() {
return text;
}
public String text;
public int fontSize = 13;
private ImageIcon iIBack = new ImageIcon(getClass().getResource("/CheckBox/Tracker_Back.png"));
private ImageIcon iIButton = new ImageIcon(getClass().getResource("/CheckBox/Tracker_Button.png"));
private ImageIcon stretchedBack, stretchedButton;
private Font fontTracker = new Font("Arial", Font.BOLD, fontSize);
private Font fontText = new Font("Arial", Font.BOLD, fontSize);
private Color textColor = new Color(103, 125, 129);
private Color buttonColor = new Color(255, 255, 255);
private int backOriginalWidth, backOriginalHeight;
private int buttonOriginalWidth, buttonOriginalHeight;
private float scale = .7f;
/**
* Constructor
*
* #param text
* set the text of this component
*/
public CustomTracker(String text) {
this.text = text;
this.setSize(this.getWidth(), iIBack.getIconHeight());
this.addMouseListener(this);
this.backOriginalWidth = iIBack.getIconWidth();
this.backOriginalHeight = iIBack.getIconHeight();
this.buttonOriginalWidth = iIButton.getIconWidth();
this.buttonOriginalHeight = iIButton.getIconHeight();
// Stretch Back
Image img = iIBack.getImage();
Image newimg = img.getScaledInstance((int) (backOriginalWidth * scale), (int) (backOriginalHeight * scale), java.awt.Image.SCALE_SMOOTH);
stretchedBack = new ImageIcon(newimg);
// Stretch Button
img = iIButton.getImage();
newimg = img.getScaledInstance((int) (buttonOriginalWidth * scale), (int) (buttonOriginalHeight * scale), java.awt.Image.SCALE_SMOOTH);
stretchedButton = new ImageIcon(newimg);
// stretch font
this.fontSize = (int)(this.fontSize * scale);
this.fontTracker = new Font("Arial", Font.BOLD, fontSize);
}
/**
* get selected value
*/
// #Override
// public boolean isSelected() {
// return this.isSelected;
// }
/**
* set selected value
*
* #param selected
* the value
*/
public void setSelected(boolean selected) {
this.isSelected = selected;
}
#Override
public Dimension getMinimumSize() {
return new Dimension(this.getWidth(), this.getHeight());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(this.getWidth(), this.getHeight());
}
/**
* paint the component
*
* #param g
* the graphics object
*/
protected void paintComponent(Graphics g) {
// create a Graphics2D Object
Graphics2D g2d = (Graphics2D) g.create();
// Draw Box Image
g2d.drawImage(stretchedBack.getImage(), 0, 0, stretchedBack.getIconWidth(), stretchedBack.getIconHeight(), this);
// Set Font-Values
g2d.setFont(fontTracker);
g2d.setColor(buttonColor);
// Set text coordinates
int x;
int y = (int) (((iIBack.getIconHeight() / 2) + (fontSize / 2) + 1) * scale);
if (this.isSelected == true) {
g2d.drawImage(stretchedButton.getImage(), (int) (40 * scale), (int) (2 * scale), stretchedButton.getIconWidth(),
stretchedButton.getIconHeight(), this);
x = (int) (15 * scale);
g2d.drawString("ON", x, y);
} else {
g2d.drawImage(stretchedButton.getImage(), 0, (int) (2 * scale), stretchedButton.getIconWidth(), stretchedButton.getIconHeight(), this);
x = (int) (37 * scale);
g2d.drawString("OFF", x, y);
}
// Draw ON or OFF
g2d.drawString(getText(), (int)((iIBack.getIconWidth() + 10) * scale), y);
// Set Font-Values
g2d.setFont(fontText);
g2d.setColor(textColor);
// Set new y-Position
y = ((stretchedBack.getIconHeight() / 2) + (fontSize / 2) + 1);
// draw the text behind the Control
g2d.drawString(getText(), stretchedBack.getIconWidth() + 10, y);
// dispose Variables
g2d.dispose();
}
#Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
}
/**
* set the text of this component
*
* #param text
* the text to display
*/
public void setText(String text) {
setText(text);
}
public void mouseClicked(MouseEvent e) {
this.isSelected = !this.isSelected;
repaint();
}
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
}
Does anyone know a solution for these problems?
i am a new programmer here and i have something to ask, i have browse a picture into my GUI (and set the path in text box also)which displays on a Label, but the label dimension is set only 100,100 while the picture is much bigger so when i open/display it into the label it get cropped , is there anyway to make it auto resize to the label size? below is my logic code on browse button and open dialog box
please any one tell me where i am wrong..
public class ImagePath extends javax.swing.JFrame {
private JPanel contentPane;
JLabel jLabel1;
String s2;
File targetFile;
BufferedImage targetImg;
public ImagePath() {
initComponents();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser jFileChooser1 = new JFileChooser();
int state = jFileChooser1.showOpenDialog(new JFrame());
jTextField1.setText("");
if (state == JFileChooser.APPROVE_OPTION) {
JOptionPane.showMessageDialog(new JFrame(), "hii");
File file = jFileChooser1.getSelectedFile();
s2 = file.toString();
jTextField1.setText(s2);
jLabel1 = new JLabel();
jLabel1.setName(s2);
jLabel1.setLocation(50, 50);
jLabel1.setSize(300, 300);
add(jLabel1);
BufferedImage bi1;
try {
bi1 = ImageIO.read(file);
ImageIcon icon1 = new ImageIcon(bi1);
jLabel1.setIcon(icon1);
Image img = icon1.getImage();
ImageIcon icon = new ImageIcon(file.getPath());
Image scaleImage = icon.getImage().getScaledInstance(28, 28, Image.SCALE_DEFAULT);
repaint();
pack();
} catch (Exception e) {
System.out.println(e);
}
} else if (state == JFileChooser.CANCEL_OPTION) {
JOptionPane.showMessageDialog(new JFrame(), "Canceled");
}
}
}
Unless you really want a nasty head ache, I would suggest taking advantage of the layout management system.
Instead of trying to set the size and location of components, let them decide how they wan to be displayed where possible.
While I personally take advantage of Netbeans form designer, I would encourage you to take the time to learn how to build your UI's by hand, it will give a greater apprication for what the form designers can do, as well ideas you can employee to make advanced UIs - IMHO
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class SimpleImageBrowser {
public static void main(String[] args) {
new SimpleImageBrowser();
}
public SimpleImageBrowser() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new SimpleImageBrowser.ImageBrowserPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ImageBrowserPane extends JPanel {
private JFileChooser fcImage = new JFileChooser();
private SimpleImageBrowser.ImagePane imagePane;
public ImageBrowserPane() {
setLayout(new BorderLayout());
imagePane = new SimpleImageBrowser.ImagePane();
add(new JScrollPane(imagePane));
JButton add = new JButton("Add");
add.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int state = fcImage.showOpenDialog(SimpleImageBrowser.ImageBrowserPane.this);
switch (state) {
case JFileChooser.APPROVE_OPTION:
File file = fcImage.getSelectedFile();
try {
BufferedImage bi1 = ImageIO.read(file);
ImageIcon icon1 = new ImageIcon(bi1);
JLabel label = new JLabel(icon1);
label.setText(file.getPath());
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.BOTTOM);
label.setForeground(Color.WHITE);
label.setBorder(new LineBorder(Color.WHITE));
imagePane.add(label);
imagePane.revalidate();
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
});
JPanel buttons = new JPanel();
buttons.add(add);
add(buttons, BorderLayout.NORTH);
}
}
public class ImagePane extends JPanel {
public ImagePane() {
setLayout(new SimpleImageBrowser.WrapLayout());
setBackground(Color.BLACK);
}
#Override
public Dimension getPreferredSize() {
return getComponentCount() == 0 ? new Dimension(200, 200) : super.getPreferredSize();
}
}
/**
* FlowLayout subclass that fully supports wrapping of components.
*/
public class WrapLayout extends FlowLayout {
private Dimension preferredLayoutSize;
/**
* Constructs a new
* <code>WrapLayout</code> with a left alignment and a default 5-unit
* horizontal and vertical gap.
*/
public WrapLayout() {
super();
}
/**
* Constructs a new
* <code>FlowLayout</code> with the specified alignment and a default 5-unit
* horizontal and vertical gap. The value of the alignment argument must be
* one of
* <code>WrapLayout</code>,
* <code>WrapLayout</code>, or
* <code>WrapLayout</code>.
*
* #param align the alignment value
*/
public WrapLayout(int align) {
super(align);
}
/**
* Creates a new flow layout manager with the indicated alignment and the
* indicated horizontal and vertical gaps.
* <p>
* The value of the alignment argument must be one of
* <code>WrapLayout</code>,
* <code>WrapLayout</code>, or
* <code>WrapLayout</code>.
*
* #param align the alignment value
* #param hgap the horizontal gap between components
* #param vgap the vertical gap between components
*/
public WrapLayout(int align, int hgap, int vgap) {
super(align, hgap, vgap);
}
/**
* Returns the preferred dimensions for this layout given the
* <i>visible</i> components in the specified target container.
*
* #param target the component which needs to be laid out
* #return the preferred dimensions to lay out the subcomponents of the
* specified container
*/
#Override
public Dimension preferredLayoutSize(Container target) {
return layoutSize(target, true);
}
/**
* Returns the minimum dimensions needed to layout the <i>visible</i>
* components contained in the specified target container.
*
* #param target the component which needs to be laid out
* #return the minimum dimensions to lay out the subcomponents of the
* specified container
*/
#Override
public Dimension minimumLayoutSize(Container target) {
Dimension minimum = layoutSize(target, false);
minimum.width -= (getHgap() + 1);
return minimum;
}
/**
* Returns the minimum or preferred dimension needed to layout the target
* container.
*
* #param target target to get layout size for
* #param preferred should preferred size be calculated
* #return the dimension to layout the target container
*/
private Dimension layoutSize(Container target, boolean preferred) {
synchronized (target.getTreeLock()) {
// Each row must fit with the width allocated to the containter.
// When the container width = 0, the preferred width of the container
// has not yet been calculated so lets ask for the maximum.
int targetWidth = target.getSize().width;
if (targetWidth == 0) {
targetWidth = Integer.MAX_VALUE;
}
int hgap = getHgap();
int vgap = getVgap();
Insets insets = target.getInsets();
int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
int maxWidth = targetWidth - horizontalInsetsAndGap;
// Fit components into the allowed width
Dimension dim = new Dimension(0, 0);
int rowWidth = 0;
int rowHeight = 0;
int nmembers = target.getComponentCount();
for (int i = 0; i < nmembers; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
// Can't add the component to current row. Start a new row.
if (rowWidth + d.width > maxWidth) {
addRow(dim, rowWidth, rowHeight);
rowWidth = 0;
rowHeight = 0;
}
// Add a horizontal gap for all components after the first
if (rowWidth != 0) {
rowWidth += hgap;
}
rowWidth += d.width;
rowHeight = Math.max(rowHeight, d.height);
}
}
addRow(dim, rowWidth, rowHeight);
dim.width += horizontalInsetsAndGap;
dim.height += insets.top + insets.bottom + vgap * 2;
// When using a scroll pane or the DecoratedLookAndFeel we need to
// make sure the preferred size is less than the size of the
// target containter so shrinking the container size works
// correctly. Removing the horizontal gap is an easy way to do this.
Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
if (scrollPane != null && target.isValid()) {
dim.width -= (hgap + 1);
}
return dim;
}
}
/*
* A new row has been completed. Use the dimensions of this row
* to update the preferred size for the container.
*
* #param dim update the width and height when appropriate
* #param rowWidth the width of the row to add
* #param rowHeight the height of the row to add
*/
private void addRow(Dimension dim, int rowWidth, int rowHeight) {
dim.width = Math.max(dim.width, rowWidth);
if (dim.height > 0) {
dim.height += getVgap();
}
dim.height += rowHeight;
}
}
}
I've included WrapLayout by Rob Camick (who lurks about the place) because, to be quite frank, none of the other layout managers gave me the effect I wanted.
I also set the label's text with the path of the image
Take a look at Using layout Managers and A Visual Guide to Layout Managers
Take a look at WrapLayout
Updated with text fields
If you want to associate a text field with the image, then I suggest you add both the label and text field to a JPanel (using something like a BorderLayout) and then add that to your image pane...
public class ImagePane extends JPanel {
public ImagePane() {
setLayout(new SimpleImageBrowser.WrapLayout());
setBackground(Color.BLACK);
}
public void addImage(File file) throws IOException {
BufferedImage bi1 = ImageIO.read(file);
ImageIcon icon1 = new ImageIcon(bi1);
JPanel imgPane = new JPanel(new BorderLayout());
imgPane.setOpaque(false);
JLabel label = new JLabel(icon1);
imgPane.add(label);
JTextField field = new JTextField(file.getPath(), 20);
field.setEditable(false);
imgPane.add(field, BorderLayout.SOUTH);
add(imgPane);
revalidate();
}
#Override
public Dimension getPreferredSize() {
return getComponentCount() == 0 ? new Dimension(200, 200) : super.getPreferredSize();
}
}
And the updated ActionListener...
add.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int state = fcImage.showOpenDialog(SimpleImageBrowser.ImageBrowserPane.this);
switch (state) {
case JFileChooser.APPROVE_OPTION:
File file = fcImage.getSelectedFile();
try {
imagePane.addImage(file);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
});
You should cut out the call to label.setSize. You should also place all your components in in the form designer instead of producing them when you click the button. Maybe you could also add a layout manager in the bargain? This will really involve a revolt against NetBeans.