【发布时间】:2012-11-27 05:59:14
【问题描述】:
我有一个JScrollPanel,我添加一个包含图像的JPanel 到JScrollPanel 并且它可以工作,但是如果JPanel 中的图像大于JScrollPanel 在宽度、高度、或将两个面板的大小调整为大约 20x20。为什么这样做?我在JScrollPanel 的视口上使用GridBagLayout。我期待的是,如果 JPanel 大于 JScrollPanel 它将添加滚动条,但这不是正在发生的事情。有什么建议吗?
private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
WebFileChooser wfc = null;
if(wfc == null){
wfc = new WebFileChooser(this, "Open an Image");
wfc.setSelectionMode(SelectionMode.SINGLE_SELECTION);
wfc.setAvailableFilter(GlobalConstants.IMAGES_AND_FOLDERS_FILTER);
wfc.setChooseFilter(GlobalConstants.IMAGES_FILTER);
wfc.setCurrentDirectory("/Users/Ryan/Desktop");
}
wfc.setVisible(true);
if(wfc.getResult() == StyleConstants.OK_OPTION){
String file = wfc.getSelectedFile().getPath();
try{
imagePane.remove(canvas);
}catch(Exception e){
}
canvas = new Canvas();
canvas.setVisible(true);
canvas.setImage(file);
//imagePane.getViewport().setLayout(new GridBagLayout());
canvas.setSizeFromLoaded();
imagePane.getViewport().add(canvas);
imagePane.repaint();
imagePane.revalidate();
}
}
这是 Canvas 类:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pocketshop;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import pocketshop.util.ImageSync;
/**
*
* @author Ryan
*/
public class Canvas extends CanvasShadow{
public static BufferedImage image = null, preview = null;
public static int width, height;
public void setImage(String filename){
try{
Canvas.image = ImageIO.read(new File(filename));
Canvas.width = image.getWidth();
Canvas.height = image.getHeight();
ImageSync.originalPixels = new int[width * height];
ImageSync.previewPixels = new int[width * height];
Canvas.image.getRGB(0, 0, width, height, ImageSync.originalPixels, 0, width);
}catch(IOException e){
}
}
public static void setImage(BufferedImage image){
Canvas.image = image;
Canvas.width = image.getWidth();
Canvas.height = image.getHeight();
ImageSync.originalPixels = new int[width * height];
ImageSync.previewPixels = new int[width * height];
Canvas.image.getRGB(0, 0, width, height, ImageSync.originalPixels, 0, width);
}
public static void setPreview(BufferedImage img, Container parent){
preview = img;
parent.repaint();
}
public static BufferedImage deepCopy(){
ColorModel cm = Canvas.image.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = Canvas.image.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
public void setSizeFromLoaded(){
try{
this.setPreferredSize(new Dimension(Canvas.width + 10, Canvas.height + 10));
this.setSize(Canvas.width + 10, Canvas.height + 10);
}catch(Exception e){
e.getMessage();
}
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
if(Canvas.preview != null){
g.drawImage(Canvas.preview, 5, 5, width, height, Color.black, null);
}else{
g.drawImage(Canvas.image, 5, 5, width, height, Color.black, null);
}
}
}
这里是 CanvasShadow 类:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package pocketshop;
import java.awt.Color;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.border.DropShadowBorder;
public class CanvasShadow extends JXPanel{
public CanvasShadow(){
DropShadowBorder shadow = new DropShadowBorder();
shadow.setShadowColor(Color.BLACK);
shadow.setShowLeftShadow(true);
shadow.setShowRightShadow(true);
shadow.setShowBottomShadow(true);
shadow.setShowTopShadow(true);
this.setBorder(shadow);
float[] hsb = new float[3];
Color.RGBtoHSB(255, 255, 255, hsb);
this.setBackground(Color.getHSBColor(hsb[0], hsb[1], hsb[2]));
}
}
这是实际图片:http://images2.fanpop.com/images/photos/4800000/Beach-beaches-4843817-1280-800.jpg
【问题讨论】:
-
好吧,我想我应该小心我的要求。伙计,所有的静电是怎么回事?!摆脱他们。您刚刚创建了一个不能多次实例化的可重用面板,因为 Canvas 的所有实例共享同一个图像。实例变量是你的朋友。静电是魔鬼!!这是什么 ImageSync 东西?更多静力学?!
-
不要使用 remove()。只需在现有画布实例上设置文件。它将使用新图像重绘。
-
如果我摆脱了静态,我将如何从另一个无法覆盖数据的类中访问该类,例如具有调整滑块以调整图像亮度的对话框。跨度>
-
只要有一个对该类的实例引用。例如,如果 Canvas 需要与 ImageSync 通信,那么 Canvas 将有一个 ImageSync 类型的实例变量。构建 Canvas 的客户端将在构建时或通过调用 setter 方法将 ImageSync 实例提供给 Canvas 实例。我不确定为什么 Canvas 依赖于 ImageSync,因为没有它你可以做到这一点,但作为一个例子,这就是你要做的。当一个对象引用另一个对象时,它被称为依赖项。您的 Canvas 对象也与 BufferedImage 有依赖关系...
-
如果对象不管理这些依赖项的生命周期,最好让客户端提供对象所需的依赖项。使用静态作为查找其他对象实例的一种方式会锁定您,因此您永远不能拥有多个给定对象的实例。您今天可能只需要一个实例,但随着需求的变化,您可能需要两个或更多。如果你不使用静态创建另一个实例是 1 分钟的工作。使用静力学,它可能需要几天的重构才能起作用。如果您只需要一个实例调用 new 一次,然后将其传递给您的组件。