I have created a CollapsablePane which shows an EffectImageView as collapsableContent, and a Node as mainContent. The EffectImageView consists of two layered ImageViews, the bottom one having an BoxBlur effect applied on it.
When there is a ScrollEvent on the mainContent the collapsableContent will be animated accordingly by setTranslateY.
With a BoxBlur effect applied, the translation of the lower part of the collapsableContent is very unsmooth, while it is absolutely smooth without the effect.
Is there a possibility to improve the transition performance?
public class EffectImageView extends Pane {
private ImageView img;
private ImageView imgEffect;
private Rectangle clipTop;
private Rectangle clipBottom;
private DoubleProperty imageEffectHeight = new SimpleDoubleProperty();
private double effectOffset;
public EffectImageView() {
img = createCachedImageView();
imgEffect = createCachedImageView();
imgEffect.imageProperty().bind(img.imageProperty());
imgEffect.fitWidthProperty().bind(img.fitWidthProperty());
imgEffect.fitHeightProperty().bind(img.fitHeightProperty());
clipTop = new Rectangle();
clipTop.widthProperty().bind(img.fitWidthProperty());
clipTop.heightProperty().bind(img.fitHeightProperty().subtract(imageEffectHeight).subtract(translateYProperty()));
clipBottom = new Rectangle();
clipBottom.widthProperty().bind(img.fitWidthProperty());
clipBottom.heightProperty().bind(imageEffectHeight);
clipBottom.translateYProperty().bind(heightProperty().subtract(imageEffectHeight).subtract(translateYProperty()));
img.setClip(clipTop);
imgEffect.setClip(clipBottom);
getChildren().addAll(img, imgEffect);
}
private ImageView createCachedImageView() {
ImageView img = new ImageView();
img.setCache(true);
img.setCacheHint(CacheHint.SPEED);
return img;
}
public final ObjectProperty<Image> imageProperty() {
return img.imageProperty();
}
public final Image getImage() {
return img.getImage();
}
public final void setImage(Image image) {
img.setImage(image);
}
public void setImageEffect(Effect effect) {
imgEffect.setEffect(effect);
}
public final DoubleProperty imageEffectHeightProperty() {
return imageEffectHeight;
}
public void setEffectOffset(double offset) {
effectOffset = offset;
}
#Override
protected void layoutChildren() {
double w = getWidth();
double h = getHeight();
img.relocate(-effectOffset, 0);
imgEffect.relocate(-effectOffset, 0);
img.setFitWidth(w + effectOffset * 2);
img.setFitHeight(h);
}
}
Related
I have a platformer class that creates a window and spawns platforms and a "character". It uses another class platform to make platforms. The character is supposed to jump up and land on the platforms. I use the getBounds and getTopY functions for collision detection but they only work for the first platform. How can i get them to work for multiple platforms?
public class Platformer extends JPanel {
Platform platform = new Platform(this);
Character character = new Character(this);
public Platformer() {
addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
character.keyTyped(e);
}
#Override
public void keyReleased(KeyEvent e) {
character.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
character.keyPressed(e);
}
});
setFocusable(true);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
platform.Location(150,200);
platform.paint(g2d);
platform.Location(200,120);
platform.paint(g2d);
character.paint(g2d);
}
private void move(){
character.move();
}
public static void main(String args[]){
JFrame frame = new JFrame("Mini Tennis");
//create new game
Platformer platformer = new Platformer();
//add game
frame.add(platformer);
//size
frame.setSize(400, 400);
frame.setVisible(true);
//set close condition
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
platformer.move();
platformer.repaint();
try {
Thread.sleep(10);//sleep for 10 sec
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
public class Platform {
private static final int Height = 10;
private static final int Width = 60;
int x;
int Y;
private Platformer platformer;
public Platform(Platformer platformer) {
this.platformer = platformer;
}
public void Location(int xin, int yin) {
x = xin;
Y = yin;
}
public void paint(Graphics2D g) {
g.fillRect(x, Y, Width, Height);
}
public Rectangle getBounds() {
return new Rectangle(x, Y, Width, Height);
}
public int getTopPlat() {
return Y;
}
}
Actually you have only one platform. And you draw this platform twice in different places (paint function in Platformer):
platform.Location(150,200);
platform.paint(g2d);
platform.Location(200,120);
platform.paint(g2d);
Therefore I suppose you handle only one platform (with coordinates 200 and 120). You must keep all of your platforms and handle each of them separately.
I've been searching everywhere for the solution, but it has come to a dead end.
Please help!
I record and save the video as the follow:
File DirectoryFile = new File(VideoPath);
recorder.setOutputFile(DirectoryFile.getAbsolutePath());
I load all the videos and set the ListView adapter from the userPath as follow:
private File[] getNewImageFilesWithFilters() {
File directory = new File(UserSavedDirectoryPATH);
return directory.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase(Locale.getDefault()).endsWith(".mp4")
|| name.toLowerCase(Locale.getDefault()).endsWith(".mkv");
}
});
}
public void LoadListView() {
for (File file : listFile){
mVideoListViewObject = new VideoListViewObject();
mVideoListViewObject.setName(file.getName());
mVideoListViewObject.setVideoUrl(file.getAbsolutePath());
VideoListViewObject_List.add(mVideoListViewObject);
}
mVideoListViewAdapter = new VideoListAdapter(this, VideoListViewObject_List);
mListView.setAdapter(mVideoListViewAdapter);
}
The ListView Adapter:
public class VideoListAdapter extends BaseAdapter {
private List<VideoListViewObject> VideoObjectList;
private Context mContext;
public VideoListAdapter(Context context, List<VideoListViewObject> newList){
this.mContext = context;
this.VideoObjectList = newList;
}
#Override
public int getCount() {
return VideoObjectList.size();
}
#Override
public VideoListViewObject getItem(int position) {
return VideoObjectList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.listview_layout, parent, false);
viewHolder.imageView = (ImageView)convertView.findViewById(R.id.ListViewImage);
viewHolder.layout = (RelativeLayout)convertView.findViewById(R.id.ListViewLayout);
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder)convertView.getTag();
}
Bitmap bmThumbnail = ThumbnailUtils.createVideoThumbnail(VideoObjectList.get(position).getVideoUrl(),Thumbnails.MICRO_KIND);
viewHolder.imageView.setImageBitmap(bmThumbnail);
The problem is the list is slow to load, especially when there are a lot of videos.
This causes my VideoaAtivity to start very slow.
I love Piscasso and Universal Image Loader, but they only support images.
Does anyone know a better solution or a library that would help with the performance?
Thank you very much.
I just modified my own application to do similar logic to pre-create the thumbnails which made the list scroll very fast at the start, Add the thumbnail bitmap to the videoListViewObject and create the thumbnail
when loading the video list. this way you do not have to create it every time getView is called in your adapter.
public class VideoListViewObject{
private Bitmap bitmap = null;
............................
public void setBitmap(Bitmap bitmap)
{
this.bitmap = bitmap;
}
public Bitmap getBitmap()
{
return this.bitmap;
}
}
public void LoadListView() {
for (File file : listFile){
mVideoListViewObject = new VideoListViewObject();
mVideoListViewObject.setName(file.getName());
mVideoListViewObject.setVideoUrl(file.getAbsolutePath());
Bitmap bmThumbnail = ThumbnailUtils.createVideoThumbnail(VideoObjectList.get(position).getVideoUrl(),Thumbnails.MICRO_KIND);
mVideoListViewObject.setBitmap(bmThumbnail);
VideoListViewObject_List.add(mVideoListViewObject);
}
mVideoListViewAdapter = new VideoListAdapter(this, VideoListViewObject_List);
mListView.setAdapter(mVideoListViewAdapter);
}
then change your BaseAdapter code to only create the thumbnail if it is null,
public class VideoListAdapter extends BaseAdapter {
private List<VideoListViewObject> VideoObjectList;
private Context mContext;
public VideoListAdapter(Context context, List<VideoListViewObject> newList){
this.mContext = context;
this.VideoObjectList = newList;
}
#Override
public int getCount() {
return VideoObjectList.size();
}
#Override
public VideoListViewObject getItem(int position) {
return VideoObjectList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.listview_layout, parent, false);
viewHolder.imageView = (ImageView)convertView.findViewById(R.id.ListViewImage);
viewHolder.layout = (RelativeLayout)convertView.findViewById(R.id.ListViewLayout);
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder)convertView.getTag();
}
VideoListViewObject mVideoListViewObject = getItem(position);
Bitmap bmThumbnail = mVideoListViewObject.getBitmap();
if(bmThumbnail==null)
{
bmThumbnail = ThumbnailUtils.createVideoThumbnail(VideoObjectList.get(position).getVideoUrl(),Thumbnails.MICRO_KIND);
}
viewHolder.imageView.setImageBitmap(bmThumbnail);
I am working on an application where I want to implement a menu. I have a GameState and a MainMenu class. Both extends Group. I can't figure out how to write a change listener to the Main.state, so when it changes from .MENU to .GAME the scenes will switch.
Here's is a part of the MainMenu class:
public class MainMenu extends Group {
private final Image background;
private final Rectangle bgRect;
private final int buttonNo = 3;
private MenuButton[] buttons;
private final double xStart = -200;
private final double yStart = 100;
private Group root;
private Scene scene;
public MainMenu () {
background = new Image(getClass().getResource("mainmenuBg.png").toString());
bgRect = new Rectangle(660,660);
bgRect.setFill(new ImagePattern(background));
root = new Group();
scene = new Scene(root, 650, 650);
scene.setCamera(new PerspectiveCamera());
root.getChildren().add(bgRect);
initButtons(root);
//Start game
buttons[0].setOnMouseClicked(new EventHandler<Event>() {
#Override
public void handle(Event t) {
Main.state = STATE.GAME;
}
});
//Options
buttons[1].setOnMouseClicked(new EventHandler<Event>() {
#Override
public void handle(Event t) {
//options menu will come here
}
});
//Exit
buttons[2].setOnMouseClicked(new EventHandler<Event>() {
#Override
public void handle(Event t) {
Platform.exit();
}
});
}
//...
}
The main class:
public class Main extends Application {
public int difficulty = 1;
GameState gameState;
MainMenu mainMenu;
public enum STATE {
MENU,
GAME
}
public static STATE state = STATE.MENU;
#Override
public void start(Stage stage) {
stage.resizableProperty().setValue(false);
stage.setTitle("Main");
Scene scene = new Scene(new StackPane(), 650, 650);
stage.setScene(scene);
stage.show();
if(Main.state == STATE.MENU)
enterMainMenu(stage);
if(Main.state == STATE.GAME)
enterGameState(stage);
}
//...
}
Any help would be appreciated.
I have succeeded to find a good solution.
I have removed the scene field from these classes, and added the super method in the constructors, than added the elements to the class (this.getChildren().addAll(..)).
Finally, here's my main controller:
public class Main extends Application {
public int difficulty = 1;
public GameState gameState = new GameState(difficulty);
public MainMenu mainMenu = new MainMenu();;
StackPane stackPane = new StackPane();
#Override
public void start(final Stage stage) {
stage.resizableProperty().setValue(false);
stage.setTitle("Main");
Scene scene = new Scene(stackPane, 650, 650);
scene.setCamera(new PerspectiveCamera());
stage.setScene(scene);
stage.show();
stackPane.getChildren().add(mainMenu);
mainMenu.getStartButton().setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
changeScene(gameState);
try {
gameState.startGame();
} catch (InterruptedException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public void changeScene(Parent newPage) {
stackPane.getChildren().add(newPage);
EventHandler<ActionEvent> finished = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
stackPane.getChildren().remove(0);
}
};
final Timeline switchPage = new Timeline(
new KeyFrame(Duration.seconds(0), new KeyValue(stackPane.getChildren().get(1).opacityProperty(), 0.0), new KeyValue(stackPane.getChildren().get(0).opacityProperty(), 1.0)),
new KeyFrame(Duration.seconds(3), finished, new KeyValue(stackPane.getChildren().get(1).opacityProperty(), 1.0), new KeyValue(stackPane.getChildren().get(0).opacityProperty(), 0.0))
);
switchPage.play();
}
}
i'm using universal image loader to populate thumbnails into gridview from assets gallary but images are loading slowly during scrolling up or down so i think because images are being loaded with it's current resolution so how i can change the resolution of the images for example i used to use createScaledBitmap to scale down the bitmap
Here is my code :
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private List<String> mList;
private int mheight;
private int mwidth;
private InputStream is;
private HomePage homePage;
private ImageLoader imageLoader;
public ImageAdapter(Context context, List<String> list, int height, int width) {
mContext = context;
mList = list;
mheight = height;
mwidth = width;
ImageLoader imageLoader = ImageLoader.getInstance();
this.imageLoader = imageLoader;
}
#Override
public int getCount() {
return mList.size();
}
#Override
public Object getItem(int position) {
return mList.get(position).toString();
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
} else {
imageView = (ImageView) convertView;
}
File cacheDir = new File(Environment.getExternalStorageDirectory(), "UniversalImageLoader/Cache");
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(mContext)
.threadPoolSize(5)
.memoryCacheExtraOptions(mwidth/3, mwidth/3)
.threadPriority(Thread.MIN_PRIORITY )
.memoryCache(new UsingFreqLimitedMemoryCache(5000000)) // You can pass your own memory cache implementation
.discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
.build();
imageLoader.init(config);
//
//
//display options
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.loading)
.showImageForEmptyUri(R.drawable.loading)
.cacheInMemory()
.cacheOnDisc()
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY)
.build();
// // Create configuration for ImageLoader
String imString = mList.get(position);
String imageUria = "assets://"+imString;
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(mwidth/3, mwidth/3));
imageLoader.displayImage(imageUria, imageView ,options );
return imageView ;
}
}
I managed to increase an image of JLabel(which has an imageIcon stored in). When I press the increase size button, the original size of the image is increased on the panel, which is exactly what I want. However, when I click on my decrease size button(I figured dividing it by the scale might fix it)the label decreases, but the actual image appearance(size I guess)is changed. It's not decreasing the size, the same way my increase button increases the size. I have spent hours trying to figure out why by multiplying it, I am able to increase the size of a the label and the image in it(which implies that not just the label is increasing, the actual image is too)but for decrease(I'm dividing instead of multiplying)it doesn't work. Here is both my increase and decrease listener.
public class IncreaseSizeListener implements ActionListener {
static JLabel increasedLabel;
#Override
public void actionPerformed(ActionEvent e) {
increasedLabel = CardLabelListener.selectedLabel;
Icon icon = CardLabelListener.selectedLabel.getIcon();
int scale =2;
System.out.println("Increased size fired");
//I can now resize images, based on my needs
BufferedImage bi = new BufferedImage(
scale*icon.getIconWidth(),
scale*icon.getIconHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.scale(scale,scale);
icon.paintIcon(null,g,0,0);
g.dispose();
JLabel temp = new JLabel(new ImageIcon(bi));
//to ensure proper size is kept for the enlarged image
CardLabelListener.selectedLabel.setSize(icon.getIconWidth()*scale, icon.getIconHeight()*(scale));
CardLabelListener.selectedLabel.setIcon(temp.getIcon());
CardLabelListener.selectedLabel.updateUI();
}
}
public class DecreaseSizeListener implements ActionListener {
static JLabel increasedLabel;
#Override
public void actionPerformed(ActionEvent e) {
increasedLabel = CardLabelListener.selectedLabel;
Icon icon = CardLabelListener.selectedLabel.getIcon();
int scale =2;
//I can now resize images, based on my needs
BufferedImage bi = new BufferedImage(
icon.getIconWidth()/scale,
icon.getIconHeight()/scale,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.scale(scale,scale);
icon.paintIcon(null,g,0,0);
g.dispose();
JLabel temp = new JLabel(new ImageIcon(bi));
//to ensure proper size is kept for the enlarged image
CardLabelListener.selectedLabel.setSize( (icon.getIconWidth()/scale), (icon.getIconHeight()/(scale)));
CardLabelListener.selectedLabel.setIcon(temp.getIcon());
CardLabelListener.selectedLabel.updateUI();
}
}
Change g.scale(scale,scale); to g.scale(0.5d,0.5d); in your decrease action listener
Or you could do this...
int scale = 0.5;
//I can now resize images, based on my needs
BufferedImage bi = new BufferedImage(
icon.getIconWidth() * scale,
icon.getIconHeight() * scale,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.scale(scale,scale);
icon.paintIcon(null,g,0,0);
g.dispose();
// This really isn't required...
//JLabel temp = new JLabel(new ImageIcon(bi));
//to ensure proper size is kept for the enlarged image
// There is a better way...
//CardLabelListener.selectedLabel.setSize( (icon.getIconWidth()/scale), (icon.getIconHeight()/(scale)));
// This isn't required
//CardLabelListener.selectedLabel.setIcon(temp.getIcon());
// This doesn't do what you think it does...
//CardLabelListener.selectedLabel.updateUI();
CardLabelListener.selectedLabel.setIcon(new ImageIcon(bi));
CardLabelListener.selectedLabel.setSize(CardLabelListener.selectedLabel.getPreferredSize());
Now both the increase and decrease algorithm's are just about the same (except for the factor), you should be able to use a single method ;)
This is pretty much the code I ended up with...
public class ScaleMyIcon {
public static void main(String[] args) {
new ScaleMyIcon();
}
public ScaleMyIcon() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ScaleMyIconPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected class ScaleMyIconPane extends JPanel {
public ScaleMyIconPane() {
setLayout(new BorderLayout());
ImageIcon image = null;
try {
image = new ImageIcon(ImageIO.read(getClass().getResource("/stormtrooper-tie.jpg")));
} catch (IOException ex) {
ex.printStackTrace();
}
JLabel label = new JLabel(image);
add(label);
JPanel buttons = new JPanel();
JButton increase = new JButton("+");
JButton decrease = new JButton("-");
buttons.add(increase);
buttons.add(decrease);
increase.addActionListener(new IncreaseSizeListener(label));
decrease.addActionListener(new DecreaseSizeListener(label));
add(buttons, BorderLayout.SOUTH);
}
}
public class Scaler {
public Icon getScaledInstance(Icon original, double scale) {
BufferedImage bi = new BufferedImage(
(int)Math.round(scale * original.getIconWidth()),
(int)Math.round(scale * original.getIconHeight()),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.scale(scale, scale);
original.paintIcon(null, g, 0, 0);
g.dispose();
return new ImageIcon(bi);
}
}
public class IncreaseSizeListener extends Scaler implements ActionListener {
private JLabel increasedLabel;
private IncreaseSizeListener(JLabel label) {
increasedLabel = label;
}
#Override
public void actionPerformed(ActionEvent e) {
Icon icon = increasedLabel.getIcon();
int scale = 2;
increasedLabel.setIcon(getScaledInstance(icon, scale));
}
}
public class DecreaseSizeListener extends Scaler implements ActionListener {
private JLabel decreasedLabel;
private DecreaseSizeListener(JLabel label) {
decreasedLabel = label;
}
#Override
public void actionPerformed(ActionEvent e) {
Icon icon = decreasedLabel.getIcon();
decreasedLabel.setIcon(getScaledInstance(icon, 0.5d));
}
}
}
UPDATED with different approach
While I was mucking around with it, I noticed two issues. There was no coalition between the up and down scales and you were never using the original image to scale against, you were always scaling the dirty image. Try scaling the image down and back up again.
This is my take on how to overcome those issues
public class ScaleMyIcon {
public static void main(String[] args) {
new ScaleMyIcon();
}
public ScaleMyIcon() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ScaleMyIconPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected class ScaleMyIconPane extends JPanel {
public ScaleMyIconPane() {
setLayout(new BorderLayout());
ImageIcon image = null;
try {
image = new ImageIcon(ImageIO.read(getClass().getResource("/stormtrooper-tie.jpg")));
} catch (IOException ex) {
ex.printStackTrace();
}
JLabel label = new JLabel(image);
add(label);
JPanel buttons = new JPanel();
JButton increase = new JButton("+");
JButton decrease = new JButton("-");
buttons.add(increase);
buttons.add(decrease);
increase.addActionListener(new IncreaseSizeListener(label));
decrease.addActionListener(new DecreaseSizeListener(label));
add(buttons, BorderLayout.SOUTH);
}
}
public static class Scalable {
private JLabel label;
private Icon original;
private static double scale = 1;
private Scalable(JLabel label) {
this.label = label;
original = label.getIcon();
}
public JLabel getLabel() {
return label;
}
public double getScale() {
return scale;
}
public void setScale(double scale) {
this.scale = scale;
}
public void incrementScale(double factor) {
setScale(getScale() + factor);
}
public Icon getScaledInstance() {
BufferedImage bi = new BufferedImage(
(int) Math.round(scale * original.getIconWidth()),
(int) Math.round(scale * original.getIconHeight()),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.scale(scale, scale);
original.paintIcon(null, g, 0, 0);
g.dispose();
return new ImageIcon(bi);
}
}
public class IncreaseSizeListener extends Scalable implements ActionListener {
public IncreaseSizeListener(JLabel label) {
super(label);
}
#Override
public void actionPerformed(ActionEvent e) {
incrementScale(0.05);
getLabel().setIcon(getScaledInstance());
}
}
public class DecreaseSizeListener extends Scalable implements ActionListener {
private DecreaseSizeListener(JLabel label) {
super(label);
}
#Override
public void actionPerformed(ActionEvent e) {
incrementScale(-0.05);
getLabel().setIcon(getScaledInstance());
}
}
}