How to update new tab title? - java

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);
}
}

Related

Displaying VLCJ in Jpanel in JFrame

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?

Canvas shows content only by minimizing and resizing the window

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);
}
}

IntelliJ IDEA cannot drop component onto form

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?

problems revalidating/repainting button panel

I've been googling for hours trying a million different subtle changes all to no avail, so I figure my best bet is to pick the brains of people more skilled than I.
I'm writing a class that loads a bunch of buttons from a database and the goal is to offer the user the ability to arrange the buttons to their liking, however, for some reason, I can't seem to get the frame to revalidate or repaint. The buttons will move around, but they will not rearrange as I have coded them to. The organization seems to be working correctly, ie the code involved in making the re arrangement when the mouse button is released, its just that the components will only stay where they are dragged and dropped, even though they are re ordered in their respective List.
The code is long, I didn't want to have to post the whole class as it may turn some people off but I don't know where I'm making the mistake so I think it would be in my best interest to post the whole thing. The main area of concern is mouseReleased(MouseEvent e) {...} and the repaint()/refresh() method, however, there could be something that I'm missing elsewhere.
tl;dr:
I'm basically just trying to perform a setBounds() after the user drags and drops the buttons in the order they want but the buttons stay in the same spot they are dragged and dropped, and won't revalidate() or repaint(). I can't even removeAll to clear the panel of components and reload.
Thank you in advanced. Here's my code:
public class AdminButtonEditor extends javax.swing.JFrame {
public AdminButtonEditor(OrderView parent) { ...
...
Component[] components = buttonsPanel.getComponents();
for (int i = 0; i < components.length; i++) {
Component c = components[i];
if (c instanceof JButton) {
JButton jb = (JButton) c;
jb.setFocusable(false);
buttons.add(new MyJButton(...));
}
}
for (int i = 0; i < buttons.size(); i++) {
buttons.get(i).addTo(editPanel);
buttons.get(i).orderIndex=modButtonList.get(i).menuModifier.getViewOrderValue();
buttons.get(i).idx=i;
}
EventHandler eh = new EventHandler();
addWindowListener(eh);
editPanel.addMouseMotionListener(eh);
editPanel.addMouseListener(eh);
contentPane.add(editPanel, BorderLayout.CENTER);
}
protected void refresh() {
if (!buttons.isEmpty() && buttons.get(0) != null) {
contentPane.remove(editPanel);
editPanel.removeAll();
for (int i = 0; i < buttons.size(); i++) {
MyJButton s = buttons.get(i);
s.addTo(editPanel);
}
contentPane.add(editPanel, BorderLayout.CENTER);
editPanel.repaint();
}
}
public void paint(Graphics g) {
refresh();
super.paint(g);
}
private int getSelectionIndex(int x, int y) {
int s=-1;
for (int i=buttons.size()-1; i>=0;i--){
if (buttons.get(i).contains(x, y)) {
s = i;
break;
}
}
return s;
}
private class EventHandler implements MouseInputListener,WindowListener, ActionListener {
private int selectionIndex, startX, startY, lastX, lastY;
private MyJButton selected;
private boolean moving=false;
....
....
public void mouseReleased(MouseEvent e) {
if (moving){
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
moving=false;
int dropX=e.getX();
int dropY=e.getY();
int row = dropY/selected.height;
int col = dropX/selected.width;
int idx=(row*3+col)-1;
int oldIdx=buttons.indexOf(selected);
insertIntoList(idx,oldIdx);
}
if (selected!=null){
selected.unHighLight();
selected=null;
}
Collections.sort(buttons);
for (int i=0;i<buttons.size();i++){
//modButtonList.get(buttons.get(i).idx).menuModifier.setViewOrderValue(buttons.get(i).orderIndex);
}
editPanel.validate();
repaint();
}
private void insertIntoList(int idx, int oldIdx) {
MyJButton temp = buttons.get(idx);
int tempid=buttons.get(idx).idx;
buttons.set(idx, new MyJButton(selected.text,selected.x,selected.y,selected.width,selected.height,selected.idx));
buttons.get(idx).orderIndex=temp.orderIndex;
if (idx<oldIdx){
int id;
for (int i=oldIdx;i>idx+1;i--){
id=buttons.get(i).orderIndex;
buttons.set(i, new MyJButton(buttons.get(i-1).text,buttons.get(i-1).x,buttons.get(i-1).y,buttons.get(i-1).width,buttons.get(i-1).height,buttons.get(i-1).idx));
buttons.get(i).orderIndex=id;
}
id = buttons.get(idx+1).orderIndex;
buttons.set(idx+1,new MyJButton(temp.text,temp.x,temp.y,temp.width,temp.height,temp.idx));
buttons.get(idx+1).orderIndex=id;
} else if (idx>oldIdx) {
int id;
for (int i=oldIdx;i<idx-1;i++){
id=buttons.get(i).orderIndex;
buttons.set(i, new MyJButton(buttons.get(i+1).text,buttons.get(i+1).x,buttons.get(i+1).y,buttons.get(i+1).width,buttons.get(i+1).height,buttons.get(i+1).idx));
buttons.get(i).orderIndex=id;
}
id = buttons.get(idx-1).orderIndex;
buttons.set(idx-1,new MyJButton(temp.text,temp.x,temp.y,temp.width,temp.height,temp.idx));
buttons.get(idx-1).orderIndex=id;;
} else {
buttons.get(idx).x=buttons.get(idx).originx;
buttons.get(idx).y=buttons.get(idx).originy;
}
repaint();
}
public void mouseDragged(MouseEvent e) {
if (moving) {
Graphics g = editPanel.getGraphics();
g.setColor(Color.black);
g.drawLine(selected.getXPos(), 0, selected.getXPos(),editPanel.getWidth());
g.drawLine(0, selected.getYPos(), editPanel.getHeight(), selected.getYPos());
selected.moveBy(e.getX()-lastX, e.getY()-lastY);
g.setXORMode(Color.black);
g.drawLine(selected.getXPos(), 0, selected.getXPos(), editPanel.getWidth());
g.drawLine(0, selected.getYPos(), editPanel.getHeight(), selected.getYPos());
lastX=e.getX();
lastY=e.getY();
repaint();
}
}
....
}
private class MyJButton extends JButton implements Comparable {
private int orderIndex,idx;
private int x, y, width, height,originx,originy;
private String text;
public Border DEFAULT_BORDER;// new SoftBevelBorder(BevelBorder.RAISED);
public Border SELECT_BORDER = BorderFactory.createLineBorder(Color.RED, 3, true);
public MyJButton(String text, int x, int y, int width, int height) {
....
setFocusable(false);
}
public MyJButton(String text, int x, int y, int width, int height,int idx) {....}
public void addTo(JPanel p) {
setBounds(x, y, width, height);
p.add(this);
}
#Override
public boolean contains(int x, int y) {
int x1 = x, y1 = y;
if (x1 >= this.x && y1 >= this.y && x1 <= this.x + width && y1 <= this.y + height) {
return true;
} else {
return false;
}
}
#Override
public void setSize(int w, int h) {
width = w;
height = h;
}
....
public void moveBy(int dx, int dy) {
x += dx;
y += dy;
}
#Override
public void resize(int newWidth, int newHeight) {
this.width = newWidth;
this.height = newHeight;
setBounds(x, y, width, height);
}
public int compareTo(Object o) {
MyJButton mjb = (MyJButton)o;
return this.idx-mjb.idx;
}
}
}
+1 to GagandeepBalis comment.
Okay so I found this very cool and decided to look into it more.
I came up with some logic which will be needed for it to work, maybe not the best but...:
1) We need to make our JButtons draggable ( thank you #camickr and his DragLayout) :)
2) When a JButtons is dragged and than dropped i.e on mouseReleased(..) we should check if a our dragged buttons collide with any others
3) we check whether a JButton collides with another by getting the JButton image and counting how many opaque pixels of the JButton, we are dragging, are covering another button.
4) sort the number of collisions and find the highest, this will be used so we can see where to insert the JButton we dragged. i.e it will be inserted by component with the most collisions.
5) sort the ArrayList which holds the buttons to match the changes
6) remove all buttons and re-add them using the Array (and thus they will be re-ordered).
Here is an example (Most code takes place in overridden ComponentMover mouseReleased(..) method):
Before dragging anything:
after dragging button 4 over button 1 and letting go of mouse button:
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DragButtons {
ArrayList<JButton> buttons = new ArrayList<>();
public DragButtons() {
initComponents();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new DragButtons();
}
});
}
private void initComponents() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel panel = new JPanel(new GridLayout(2, 2));
ComponentMover cm = new ComponentMover() {
#Override
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
HashMap<Integer, JButton> collisions = new HashMap<>();
JButton draggedButton = (JButton) e.getSource();
for (JButton btn : buttons) {//iterate through all buttons and get the number of collsions of each
if (btn != draggedButton) {//dont chck button we were dragging
int col = checkPerPixelCollision(draggedButton, btn);
System.out.println("Button " + btn.getText());
System.out.println(col);
collisions.put(col, btn);
}
}
//lets get the button which had most collisions
int maxCollisions = 0;
JButton intersectingButton = null;
for (Map.Entry<Integer, JButton> entry : collisions.entrySet()) {
Integer collisionCount = entry.getKey();
JButton button = entry.getValue();
if (collisionCount > maxCollisions) {
maxCollisions = collisionCount;
intersectingButton = button;
}
}
boolean reLayout = false;
if (maxCollisions > 0) {//check if there was any
System.out.println("Button " + draggedButton.getText() + " is intersecting more of Button " + intersectingButton.getText());
System.out.println("Collisions: " + maxCollisions);
reLayout = true;
} else {
System.out.println("No change made");
reLayout = false;
}
ArrayList<JButton> tmpButtons = (ArrayList<JButton>) buttons.clone();//create clone of buttons
if (reLayout) {//a button as moved and panel needs to be layed out
buttons.clear();//clear old buttons
for (JButton b : tmpButtons) {//re-order jbuttons
if (b == intersectingButton) {
buttons.add(draggedButton);
} else if (b == draggedButton) {
buttons.add(intersectingButton);
} else {
buttons.add(b);
}
}
panel.removeAll();//remove all buttons
for (JButton btn : buttons) {//iterate through all buttons and get the number of collsions of each
panel.add(btn);//re-add buttons according to arraylist
}
panel.revalidate();
panel.repaint();
//re-order the Array of buttons to fit
//remove all button and re add them using sorted array
}
}
};
for (int i = 0; i < 4; i++) {
JButton b = new JButton(String.valueOf(i + 1));
buttons.add(b);
panel.add(b);
cm.registerComponent(b);
}
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public HashSet<String> getMask(JButton e) {
HashSet<String> mask = new HashSet<>();
int pixel, a;
BufferedImage bi = null;
try {
bi = componentToImage(e, e.getBounds()); //gets the current image being shown
} catch (IOException ex) {
Logger.getLogger(DragButtons.class.getName()).log(Level.SEVERE, null, ex);
}
for (int i = 0; i < bi.getWidth(); i++) { // for every (x,y) component in the given box,
for (int j = 0; j < bi.getHeight(); j++) {
pixel = bi.getRGB(i, j); // get the RGB value of the pixel
a = (pixel >> 24) & 0xff;
if (a != 0) { // if the alpha is not 0, it must be something other than transparent
mask.add((e.getX() + i) + "," + (e.getY() - j)); // add the absolute x and absolute y coordinates to our set
}
}
}
return mask; //return our set
}
public static BufferedImage componentToImage(Component component, Rectangle region) throws IOException {
BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = img.getGraphics();
g.setColor(component.getForeground());
g.setFont(component.getFont());
component.paintAll(g);
ImageIO.write(img, "png", new File("c:/saved.png"));
return img;
}
// Returns true if there is a collision between object a and object b
public int checkPerPixelCollision(JButton b, JButton b2) {
// This method detects to see if the images overlap at all. If they do, collision is possible
int ax1 = (int) b2.getX();
int ay1 = (int) b2.getY();
int ax2 = ax1 + (int) b2.getWidth();
int ay2 = ay1 + (int) b2.getHeight();
int bx1 = (int) b.getX();
int by1 = (int) b.getY();
int bx2 = bx1 + (int) b.getWidth();
int by2 = by1 + (int) b.getHeight();
if (by2 < ay1 || ay2 < by1 || bx2 < ax1 || ax2 < bx1) {
return 0; // Collision is impossible.
} else { // Collision is possible.
// get the masks for both images
HashSet<String> maskPlayer1 = getMask(b2);
HashSet<String> maskPlayer2 = getMask(b);
maskPlayer1.retainAll(maskPlayer2); // Check to see if any pixels in maskPlayer2 are the same as those in maskPlayer1
if (maskPlayer1.size() > 0) { // if so, than there exists at least one pixel that is the same in both images, thus
return maskPlayer1.size();
}
}
return 0;
}
}
class ComponentMover extends MouseAdapter {
private Insets dragInsets = new Insets(0, 0, 0, 0);
private Dimension snapSize = new Dimension(1, 1);
private Insets edgeInsets = new Insets(0, 0, 0, 0);
private boolean changeCursor = true;
private boolean autoLayout = false;
private Class destinationClass;
private Component destinationComponent;
private Component destination;
private Component source;
private Point pressed;
private Point location;
private Cursor originalCursor;
private boolean autoscrolls;
private boolean potentialDrag;
/**
* Constructor for moving individual components. The components must be
* regisetered using the registerComponent() method.
*/
public ComponentMover() {
}
/**
* Constructor to specify a Class of Component that will be moved when drag
* events are generated on a registered child component. The events will be
* passed to the first ancestor of this specified class.
*
* #param destinationClass the Class of the ancestor component
* #param component the Components to be registered for forwarding drag
* events to the ancestor Component.
*/
public ComponentMover(Class destinationClass, Component... components) {
this.destinationClass = destinationClass;
registerComponent(components);
}
/**
* Constructor to specify a parent component that will be moved when drag
* events are generated on a registered child component.
*
* #param destinationComponent the component drage events should be
* forwareded to
* #param components the Components to be registered for forwarding drag
* events to the parent component to be moved
*/
public ComponentMover(Component destinationComponent, Component... components) {
this.destinationComponent = destinationComponent;
registerComponent(components);
}
/**
* Get the auto layout property
*
* #return the auto layout property
*/
public boolean isAutoLayout() {
return autoLayout;
}
/**
* Set the auto layout property
*
* #param autoLayout when true layout will be invoked on the parent
* container
*/
public void setAutoLayout(boolean autoLayout) {
this.autoLayout = autoLayout;
}
/**
* Get the change cursor property
*
* #return the change cursor property
*/
public boolean isChangeCursor() {
return changeCursor;
}
/**
* Set the change cursor property
*
* #param changeCursor when true the cursor will be changed to the
* Cursor.MOVE_CURSOR while the mouse is pressed
*/
public void setChangeCursor(boolean changeCursor) {
this.changeCursor = changeCursor;
}
/**
* Get the drag insets
*
* #return the drag insets
*/
public Insets getDragInsets() {
return dragInsets;
}
/**
* Set the drag insets. The insets specify an area where mouseDragged events
* should be ignored and therefore the component will not be moved. This
* will prevent these events from being confused with a MouseMotionListener
* that supports component resizing.
*
* #param dragInsets
*/
public void setDragInsets(Insets dragInsets) {
this.dragInsets = dragInsets;
}
/**
* Get the bounds insets
*
* #return the bounds insets
*/
public Insets getEdgeInsets() {
return edgeInsets;
}
/**
* Set the edge insets. The insets specify how close to each edge of the
* parent component that the child component can be moved. Positive values
* means the component must be contained within the parent. Negative values
* means the component can be moved outside the parent.
*
* #param edgeInsets
*/
public void setEdgeInsets(Insets edgeInsets) {
this.edgeInsets = edgeInsets;
}
/**
* Remove listeners from the specified component
*
* #param component the component the listeners are removed from
*/
public void deregisterComponent(Component... components) {
for (Component component : components) {
component.removeMouseListener(this);
}
}
/**
* Add the required listeners to the specified component
*
* #param component the component the listeners are added to
*/
public void registerComponent(Component... components) {
for (Component component : components) {
component.addMouseListener(this);
}
}
/**
* Get the snap size
*
* #return the snap size
*/
public Dimension getSnapSize() {
return snapSize;
}
/**
* Set the snap size. Forces the component to be snapped to the closest grid
* position. Snapping will occur when the mouse is dragged half way.
*/
public void setSnapSize(Dimension snapSize) {
if (snapSize.width < 1
|| snapSize.height < 1) {
throw new IllegalArgumentException("Snap sizes must be greater than 0");
}
this.snapSize = snapSize;
}
/**
* Setup the variables used to control the moving of the component:
*
* source - the source component of the mouse event destination - the
* component that will ultimately be moved pressed - the Point where the
* mouse was pressed in the destination component coordinates.
*/
#Override
public void mousePressed(MouseEvent e) {
source = e.getComponent();
int width = source.getSize().width - dragInsets.left - dragInsets.right;
int height = source.getSize().height - dragInsets.top - dragInsets.bottom;
Rectangle r = new Rectangle(dragInsets.left, dragInsets.top, width, height);
if (r.contains(e.getPoint())) {
setupForDragging(e);
}
}
private void setupForDragging(MouseEvent e) {
source.addMouseMotionListener(this);
potentialDrag = true;
// Determine the component that will ultimately be moved
if (destinationComponent != null) {
destination = destinationComponent;
} else if (destinationClass == null) {
destination = source;
} else // forward events to destination component
{
destination = SwingUtilities.getAncestorOfClass(destinationClass, source);
}
pressed = e.getLocationOnScreen();
location = destination.getLocation();
if (changeCursor) {
originalCursor = source.getCursor();
source.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
// Making sure autoscrolls is false will allow for smoother dragging of
// individual components
if (destination instanceof JComponent) {
JComponent jc = (JComponent) destination;
autoscrolls = jc.getAutoscrolls();
jc.setAutoscrolls(false);
}
}
/**
* Move the component to its new location. The dragged Point must be in the
* destination coordinates.
*/
#Override
public void mouseDragged(MouseEvent e) {
Point dragged = e.getLocationOnScreen();
int dragX = getDragDistance(dragged.x, pressed.x, snapSize.width);
int dragY = getDragDistance(dragged.y, pressed.y, snapSize.height);
int locationX = location.x + dragX;
int locationY = location.y + dragY;
// Mouse dragged events are not generated for every pixel the mouse
// is moved. Adjust the location to make sure we are still on a
// snap value.
while (locationX < edgeInsets.left) {
locationX += snapSize.width;
}
while (locationY < edgeInsets.top) {
locationY += snapSize.height;
}
Dimension d = getBoundingSize(destination);
while (locationX + destination.getSize().width + edgeInsets.right > d.width) {
locationX -= snapSize.width;
}
while (locationY + destination.getSize().height + edgeInsets.bottom > d.height) {
locationY -= snapSize.height;
}
// Adjustments are finished, move the component
destination.setLocation(locationX, locationY);
}
/*
* Determine how far the mouse has moved from where dragging started
* (Assume drag direction is down and right for positive drag distance)
*/
private int getDragDistance(int larger, int smaller, int snapSize) {
int halfway = snapSize / 2;
int drag = larger - smaller;
drag += (drag < 0) ? -halfway : halfway;
drag = (drag / snapSize) * snapSize;
return drag;
}
/*
* Get the bounds of the parent of the dragged component.
*/
private Dimension getBoundingSize(Component source) {
if (source instanceof Window) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle bounds = env.getMaximumWindowBounds();
return new Dimension(bounds.width, bounds.height);
} else {
return source.getParent().getSize();
}
}
/**
* Restore the original state of the Component
*/
#Override
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
if (!potentialDrag) {
return;
}
source.removeMouseMotionListener(this);
potentialDrag = false;
if (changeCursor) {
source.setCursor(originalCursor);
}
if (destination instanceof JComponent) {
((JComponent) destination).setAutoscrolls(autoscrolls);
}
// Layout the components on the parent container
if (autoLayout) {
if (destination instanceof JComponent) {
((JComponent) destination).revalidate();
} else {
destination.revalidate();
}
destination.repaint();
}
}
}

How I can add JScroll bar to NavigableImagePanel which is an Image panel with an small navigation view?

I have the following NavigableImagePanel, it is under BSD license and I found it in the web. What I want to do with this panel is as follow:
I want to add a JScrollPane to it in order to show images in their full size and let the users to re-center the image using the small navigation panel. Right now, the panel resize the images to fit them in the current panel size. I want it to load the image in its real size and let users to navigate to different parts of the image using the navigation panel.
Source code for the panel:
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* #author pxt
*
*/
public class NavigableImagePanel extends JPanel {
/**
* <p>Identifies a change to the zoom level.</p>
*/
public static final String ZOOM_LEVEL_CHANGED_PROPERTY = "zoomLevel";
/**
* <p>Identifies a change to the zoom increment.</p>
*/
public static final String ZOOM_INCREMENT_CHANGED_PROPERTY = "zoomIncrement";
/**
* <p>Identifies that the image in the panel has changed.</p>
*/
public static final String IMAGE_CHANGED_PROPERTY = "image";
private static final double SCREEN_NAV_IMAGE_FACTOR = 0.15; // 15% of panel's width
private static final double NAV_IMAGE_FACTOR = 0.3; // 30% of panel's width
private static final double HIGH_QUALITY_RENDERING_SCALE_THRESHOLD = 1.0;
private static final Object INTERPOLATION_TYPE =
RenderingHints.VALUE_INTERPOLATION_BILINEAR;
private double zoomIncrement = 0.2;
private double zoomFactor = 1.0 + zoomIncrement;
private double navZoomFactor = 1.0 + zoomIncrement;
private BufferedImage image;
private BufferedImage navigationImage;
private int navImageWidth;
private int navImageHeight;
private double initialScale = 0.0;
private double scale = 0.0;
private double navScale = 0.0;
private int originX = 0;
private int originY = 0;
private Point mousePosition;
private Dimension previousPanelSize;
private boolean navigationImageEnabled = true;
private boolean highQualityRenderingEnabled = true;
private WheelZoomDevice wheelZoomDevice = null;
private ButtonZoomDevice buttonZoomDevice = null;
/**
* <p>Defines zoom devices.</p>
*/
public static class ZoomDevice {
/**
* <p>Identifies that the panel does not implement zooming,
* but the component using the panel does (programmatic zooming method).</p>
*/
public static final ZoomDevice NONE = new ZoomDevice("none");
/**
* <p>Identifies the left and right mouse buttons as the zooming device.</p>
*/
public static final ZoomDevice MOUSE_BUTTON = new ZoomDevice("mouseButton");
/**
* <p>Identifies the mouse scroll wheel as the zooming device.</p>
*/
public static final ZoomDevice MOUSE_WHEEL = new ZoomDevice("mouseWheel");
private String zoomDevice;
private ZoomDevice(String zoomDevice) {
this.zoomDevice = zoomDevice;
}
public String toString() {
return zoomDevice;
}
}
//This class is required for high precision image coordinates translation.
private class Coords {
public double x;
public double y;
public Coords(double x, double y) {
this.x = x;
this.y = y;
}
public int getIntX() {
return (int)Math.round(x);
}
public int getIntY() {
return (int)Math.round(y);
}
public String toString() {
return "[Coords: x=" + x + ",y=" + y + "]";
}
}
private class WheelZoomDevice implements MouseWheelListener {
public void mouseWheelMoved(MouseWheelEvent e) {
Point p = e.getPoint();
boolean zoomIn = (e.getWheelRotation() < 0);
if (isInNavigationImage(p)) {
if (zoomIn) {
navZoomFactor = 1.0 + zoomIncrement;
} else {
navZoomFactor = 1.0 - zoomIncrement;
}
zoomNavigationImage();
} else if (isInImage(p)) {
if (zoomIn) {
zoomFactor = 1.0 + zoomIncrement;
} else {
zoomFactor = 1.0 - zoomIncrement;
}
zoomImage();
}
}
}
private class ButtonZoomDevice extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
if (SwingUtilities.isRightMouseButton(e)) {
if (isInNavigationImage(p)) {
navZoomFactor = 1.0 - zoomIncrement;
zoomNavigationImage();
} else if (isInImage(p)) {
zoomFactor = 1.0 - zoomIncrement;
zoomImage();
}
} else {
if (isInNavigationImage(p)) {
navZoomFactor = 1.0 + zoomIncrement;
zoomNavigationImage();
} else if (isInImage(p)) {
zoomFactor = 1.0 + zoomIncrement;
zoomImage();
}
}
}
}
/**
* <p>Creates a new navigable image panel with no default image and
* the mouse scroll wheel as the zooming device.</p>
*/
public NavigableImagePanel() {
setOpaque(false);
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
if (scale > 0.0) {
if (isFullImageInPanel()) {
centerImage();
} else if (isImageEdgeInPanel()) {
scaleOrigin();
}
if (isNavigationImageEnabled()) {
createNavigationImage();
}
repaint();
}
previousPanelSize = getSize();
}
});
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
if (isInNavigationImage(e.getPoint())) {
Point p = e.getPoint();
displayImageAt(p);
}
}
}
public void mouseClicked(MouseEvent e){
if (e.getClickCount() == 2) {
resetImage();
}
}
});
addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)
&& !isInNavigationImage(e.getPoint())) {
Point p = e.getPoint();
moveImage(p);
}
}
public void mouseMoved(MouseEvent e) {
//we need the mouse position so that after zooming
//that position of the image is maintained
mousePosition = e.getPoint();
}
});
setZoomDevice(ZoomDevice.MOUSE_WHEEL);
}
/**
* <p>Creates a new navigable image panel with the specified image
* and the mouse scroll wheel as the zooming device.</p>
*/
public NavigableImagePanel(BufferedImage image) throws IOException {
this();
setImage(image);
}
private void addWheelZoomDevice() {
if (wheelZoomDevice == null) {
wheelZoomDevice = new WheelZoomDevice();
addMouseWheelListener(wheelZoomDevice);
}
}
private void addButtonZoomDevice() {
if (buttonZoomDevice == null) {
buttonZoomDevice = new ButtonZoomDevice();
addMouseListener(buttonZoomDevice);
}
}
private void removeWheelZoomDevice() {
if (wheelZoomDevice != null) {
removeMouseWheelListener(wheelZoomDevice);
wheelZoomDevice = null;
}
}
private void removeButtonZoomDevice() {
if (buttonZoomDevice != null) {
removeMouseListener(buttonZoomDevice);
buttonZoomDevice = null;
}
}
/**
* <p>Sets a new zoom device.</p>
*
* #param newZoomDevice specifies the type of a new zoom device.
*/
public void setZoomDevice(ZoomDevice newZoomDevice) {
if (newZoomDevice == ZoomDevice.NONE) {
removeWheelZoomDevice();
removeButtonZoomDevice();
} else if (newZoomDevice == ZoomDevice.MOUSE_BUTTON) {
removeWheelZoomDevice();
addButtonZoomDevice();
} else if (newZoomDevice == ZoomDevice.MOUSE_WHEEL) {
removeButtonZoomDevice();
addWheelZoomDevice();
}
}
/**
* <p>Gets the current zoom device.</p>
*/
public ZoomDevice getZoomDevice() {
if (buttonZoomDevice != null) {
return ZoomDevice.MOUSE_BUTTON;
} else if (wheelZoomDevice != null) {
return ZoomDevice.MOUSE_WHEEL;
} else {
return ZoomDevice.NONE;
}
}
//Called from paintComponent() when a new image is set.
private void initializeParams() {
double xScale = (double)getWidth() / image.getWidth();
double yScale = (double)getHeight() / image.getHeight();
initialScale = Math.min(xScale, yScale);
scale = initialScale;
//An image is initially centered
centerImage();
if (isNavigationImageEnabled()) {
createNavigationImage();
}
}
//Centers the current image in the panel.
private void centerImage() {
originX = (int)(getWidth() - getScreenImageWidth()) / 2;
originY = (int)(getHeight() - getScreenImageHeight()) / 2;
}
//Creates and renders the navigation image in the upper let corner of the panel.
private void createNavigationImage() {
//We keep the original navigation image larger than initially
//displayed to allow for zooming into it without pixellation effect.
navImageWidth = (int)(getWidth() * NAV_IMAGE_FACTOR);
navImageHeight = navImageWidth * image.getHeight() / image.getWidth();
int scrNavImageWidth = (int)(getWidth() * SCREEN_NAV_IMAGE_FACTOR);
int scrNavImageHeight = scrNavImageWidth * image.getHeight() / image.getWidth();
navScale = (double)scrNavImageWidth / navImageWidth;
navigationImage = new BufferedImage(navImageWidth, navImageHeight,
image.getType());
Graphics g = navigationImage.getGraphics();
g.drawImage(image, 0, 0, navImageWidth, navImageHeight, null);
}
/**
* <p>Sets an image for display in the panel.</p>
*
* #param image an image to be set in the panel
*/
public void setImage(BufferedImage image) {
BufferedImage oldImage = this.image;
this.image = image;
//Reset scale so that initializeParameters() is called in paintComponent()
//for the new image.
scale = 0.0;
firePropertyChange(IMAGE_CHANGED_PROPERTY, (Image)oldImage, (Image)image);
repaint();
}
/**
* <p>resets an image to the centre of the panel</p>
*
*/
public void resetImage() {
BufferedImage oldImage = this.image;
this.image = image;
//Reset scale so that initializeParameters() is called in paintComponent()
//for the new image.
scale = 0.0;
firePropertyChange(IMAGE_CHANGED_PROPERTY, (Image)oldImage, (Image)image);
repaint();
}
/**
* <p>Tests whether an image uses the standard RGB color space.</p>
*/
public static boolean isStandardRGBImage(BufferedImage bImage) {
return bImage.getColorModel().getColorSpace().isCS_sRGB();
}
//Converts this panel's coordinates into the original image coordinates
private Coords panelToImageCoords(Point p) {
return new Coords((p.x - originX) / scale, (p.y - originY) / scale);
}
//Converts the original image coordinates into this panel's coordinates
private Coords imageToPanelCoords(Coords p) {
return new Coords((p.x * scale) + originX, (p.y * scale) + originY);
}
//Converts the navigation image coordinates into the zoomed image coordinates
private Point navToZoomedImageCoords(Point p) {
int x = p.x * getScreenImageWidth() / getScreenNavImageWidth();
int y = p.y * getScreenImageHeight() / getScreenNavImageHeight();
return new Point(x, y);
}
//The user clicked within the navigation image and this part of the image
//is displayed in the panel.
//The clicked point of the image is centered in the panel.
private void displayImageAt(Point p) {
Point scrImagePoint = navToZoomedImageCoords(p);
originX = -(scrImagePoint.x - getWidth() / 2);
originY = -(scrImagePoint.y - getHeight() / 2);
repaint();
}
//Tests whether a given point in the panel falls within the image boundaries.
private boolean isInImage(Point p) {
Coords coords = panelToImageCoords(p);
int x = coords.getIntX();
int y = coords.getIntY();
return (x >= 0 && x < image.getWidth() && y >= 0 && y < image.getHeight());
}
//Tests whether a given point in the panel falls within the navigation image
//boundaries.
private boolean isInNavigationImage(Point p) {
return (isNavigationImageEnabled() && p.x < getScreenNavImageWidth()
&& p.y < getScreenNavImageHeight());
}
//Used when the image is resized.
private boolean isImageEdgeInPanel() {
if (previousPanelSize == null) {
return false;
}
return (originX > 0 && originX < previousPanelSize.width
|| originY > 0 && originY < previousPanelSize.height);
}
//Tests whether the image is displayed in its entirety in the panel.
private boolean isFullImageInPanel() {
return (originX >= 0 && (originX + getScreenImageWidth()) < getWidth()
&& originY >= 0 && (originY + getScreenImageHeight()) < getHeight());
}
/**
* <p>Indicates whether the high quality rendering feature is enabled.</p>
*
* #return true if high quality rendering is enabled, false otherwise.
*/
public boolean isHighQualityRenderingEnabled() {
return highQualityRenderingEnabled;
}
/**
* <p>Enables/disables high quality rendering.</p>
*
* #param enabled enables/disables high quality rendering
*/
public void setHighQualityRenderingEnabled(boolean enabled) {
highQualityRenderingEnabled = enabled;
}
//High quality rendering kicks in when when a scaled image is larger
//than the original image. In other words,
//when image decimation stops and interpolation starts.
private boolean isHighQualityRendering() {
return (highQualityRenderingEnabled
&& scale > HIGH_QUALITY_RENDERING_SCALE_THRESHOLD);
}
/**
* <p>Indicates whether navigation image is enabled.<p>
*
* #return true when navigation image is enabled, false otherwise.
*/
public boolean isNavigationImageEnabled() {
return navigationImageEnabled;
}
/**
* <p>Enables/disables navigation with the navigation image.</p>
* <p>Navigation image should be disabled when custom, programmatic navigation
* is implemented.</p>
*
* #param enabled true when navigation image is enabled, false otherwise.
*/
public void setNavigationImageEnabled(boolean enabled) {
navigationImageEnabled = enabled;
repaint();
}
//Used when the panel is resized
private void scaleOrigin() {
originX = originX * getWidth() / previousPanelSize.width;
originY = originY * getHeight() / previousPanelSize.height;
repaint();
}
//Converts the specified zoom level to scale.
private double zoomToScale(double zoom) {
return initialScale * zoom;
}
/**
* <p>Gets the current zoom level.</p>
*
* #return the current zoom level
*/
public double getZoom() {
return scale / initialScale;
}
/**
* <p>Sets the zoom level used to display the image.</p>
* <p>This method is used in programmatic zooming. The zooming center is
* the point of the image closest to the center of the panel.
* After a new zoom level is set the image is repainted.</p>
*
* #param newZoom the zoom level used to display this panel's image.
*/
public void setZoom(double newZoom) {
Point zoomingCenter = new Point(getWidth() / 2, getHeight() / 2);
setZoom(newZoom, zoomingCenter);
}
/**
* <p>Sets the zoom level used to display the image, and the zooming center,
* around which zooming is done.</p>
* <p>This method is used in programmatic zooming.
* After a new zoom level is set the image is repainted.</p>
*
* #param newZoom the zoom level used to display this panel's image.
*/
public void setZoom(double newZoom, Point zoomingCenter) {
Coords imageP = panelToImageCoords(zoomingCenter);
if (imageP.x < 0.0) {
imageP.x = 0.0;
}
if (imageP.y < 0.0) {
imageP.y = 0.0;
}
if (imageP.x >= image.getWidth()) {
imageP.x = image.getWidth() - 1.0;
}
if (imageP.y >= image.getHeight()) {
imageP.y = image.getHeight() - 1.0;
}
Coords correctedP = imageToPanelCoords(imageP);
double oldZoom = getZoom();
scale = zoomToScale(newZoom);
Coords panelP = imageToPanelCoords(imageP);
originX += (correctedP.getIntX() - (int)panelP.x);
originY += (correctedP.getIntY() - (int)panelP.y);
firePropertyChange(ZOOM_LEVEL_CHANGED_PROPERTY, new Double(oldZoom),
new Double(getZoom()));
repaint();
}
/**
* <p>Gets the current zoom increment.</p>
*
* #return the current zoom increment
*/
public double getZoomIncrement() {
return zoomIncrement;
}
/**
* <p>Sets a new zoom increment value.</p>
*
* #param newZoomIncrement new zoom increment value
*/
public void setZoomIncrement(double newZoomIncrement) {
double oldZoomIncrement = zoomIncrement;
zoomIncrement = newZoomIncrement;
firePropertyChange(ZOOM_INCREMENT_CHANGED_PROPERTY,
new Double(oldZoomIncrement), new Double(zoomIncrement));
}
//Zooms an image in the panel by repainting it at the new zoom level.
//The current mouse position is the zooming center.
private void zoomImage() {
Coords imageP = panelToImageCoords(mousePosition);
double oldZoom = getZoom();
scale *= zoomFactor;
Coords panelP = imageToPanelCoords(imageP);
originX += (mousePosition.x - (int)panelP.x);
originY += (mousePosition.y - (int)panelP.y);
firePropertyChange(ZOOM_LEVEL_CHANGED_PROPERTY, new Double(oldZoom),
new Double(getZoom()));
repaint();
}
//Zooms the navigation image
private void zoomNavigationImage() {
navScale *= navZoomFactor;
repaint();
}
/**
* <p>Gets the image origin.</p>
* <p>Image origin is defined as the upper, left corner of the image in
* the panel's coordinate system.</p>
* #return the point of the upper, left corner of the image in the panel's coordinates
* system.
*/
public Point getImageOrigin() {
return new Point(originX, originY);
}
/**
* <p>Sets the image origin.</p>
* <p>Image origin is defined as the upper, left corner of the image in
* the panel's coordinate system. After a new origin is set, the image is repainted.
* This method is used for programmatic image navigation.</p>
I've used this component before myself, but never in exactly the way you describe. There is an existing function in the code, setZoom(), that can be used to programatically set the zoom level and repaint the image. I would recommend that you experiment with that function and the zoom level.

Categories