- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以,我有一个带有菜单、工具栏和面板的 JFrame。我在面板内加载图像,但由于某些奇怪的原因(至少对我来说),它们没有正确显示在面板中。有时它们从工具栏下方开始,有时在上方。此外,图像在底部被剪切。该代码是完整示例中经过清理的示例,可以编译和测试。提前致谢。
包含框架的类:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.zip.ZipInputStream;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
public class SSCE extends JFrame {
private JComicPanel panel;
private JToolBar toolbar;
private JButton buttonZoom;
private JButton buttonPrev;
private JButton buttonNext;
private JMenuBar menuBar;
private Dimension dim;
private BufferedImage img;
private int currentPage;
private JFrame parentFrame;
public SSCE(){
super("JComic");
BorderLayout layout = new BorderLayout();
setLayout(layout);
dim = Toolkit.getDefaultToolkit().getScreenSize();
setSize((int)(dim.width /2.5),dim.height);
this.setPreferredSize(new Dimension((int) (dim.width /2.5),dim.height));
createToolbar();
createPanel();
add(toolbar,BorderLayout.NORTH);
add(panel,BorderLayout.CENTER);
createMenu();
add(menuBar);
setJMenuBar(menuBar);
panel.setVisible(true);
img = null;
pack();
parentFrame = this;
}
private void createPanel(){
Border raisedbevel, loweredbevel;
raisedbevel = BorderFactory.createRaisedBevelBorder();
loweredbevel = BorderFactory.createLoweredBevelBorder();
panel = new JComicPanel(img);
panel.setBorder(BorderFactory.createCompoundBorder(raisedbevel,loweredbevel));
}
private void createToolbar(){
toolbar = new JToolBar();
toolbar.setPreferredSize(new Dimension(dim.width,45));
toolbar.setFloatable(false);
buttonZoom = new JButton("+");
toolbar.add(buttonZoom);
buttonPrev = new JButton("<-");
toolbar.add(buttonPrev);
buttonNext = new JButton("->");
toolbar.add(buttonNext);
toolbar.setBackground(Color.RED);
}
private void createMenu(){
JMenu menuFile,menuJComic;
JMenuItem fileOpen;
JMenuItem quitJComic,aboutJComic;
menuBar = new JMenuBar();
menuJComic = new JMenu("JComic");
aboutJComic = new JMenuItem("About JComic...");
menuJComic.add(aboutJComic);
quitJComic = new JMenuItem("Quit");
quitJComic.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
);
menuJComic.add(quitJComic);
menuBar.add(menuJComic);
menuFile = new JMenu("File");
fileOpen = new JMenuItem("Open...");
fileOpen.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e) {
try {
img = ImageIO.read(new File("superman.jpg"));
currentPage = 1;
int offset = menuBar.getHeight() + toolbar.getHeight();
panel.setImage(img,parentFrame,offset);
}
catch (IOException e1) {
System.out.println(e1.getMessage());
}
}
}
);
menuFile.add(fileOpen);
menuBar.add(menuFile);
}
/**
* @param args
*/
@SuppressWarnings("deprecation")
public static void main(String[] args) {
// TODO Auto-generated method stub
SSCE f = new SSCE();
f.show();
}
}
面板类别
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JComicPanel extends JPanel{
private BufferedImage img;
private int offset;
private final float scaling = 0.5f;
public JComicPanel(BufferedImage img){
super();
this.img = img;
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e)
{
repaint();
}
});
}
public void setImage(BufferedImage img,JFrame parentFrame,int offset){
try{
int w = img.getWidth();
int h = img.getHeight();
int newW = (int)(w * scaling);
int newH = (int)(h * scaling);
BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
this.img = img;
System.out.printf("dim %d x %d",newW,newH);
this.setSize(new Dimension(newW,newH+offset));
parentFrame.pack();
}
catch(Exception e){
}
}
public Dimension getPreferredSize(){
return new Dimension(img.getWidth(),img.getHeight());
}
public void paintComponent(Graphics g){
// Draw our Image object.
super.paintComponent(g);
g.drawImage(img,0,0,getSize().width,getSize().height, this); // at location 50,10
System.out.println("painting 2");
}
}
图片 superman.jpg 可以在这里找到 http://i50.tinypic.com/2yxnc3n.jpg 。正如您所看到的,图像位于工具栏下方,但在我的完整代码中,它也位于工具栏上方。
最佳答案
让我们从这里开始...
public void setImage(BufferedImage img,JFrame parentFrame,int offset){
try{
// You're scaling the incoming image, which means you no longer
// have a reference to the original image should you want to
// change that scale...
// You're previous code...
// Don't do this. The parent container's layout manager will simple
// override it, so it's useless...
this.setSize(newW,newH);
repaint();
// This is a bad idea (personally)...
parentFrame.setSize(newW,newH+offset);
} catch(Exception e){
}
}
以这种方式调用setSize
将暂时允许组件采用您设置的大小。如果您在其后调用 invalidate()
,组件实际上会重新调整大小以满足布局管理器的要求。
更大的问题是,您正在设置父框架的大小,但您不知道框架相对于其其他组件的布局要求,例如工具栏、菜单栏和框架(例如)
这是在不考虑原始图像比例的情况下绘制图像
g.drawImage(img,0,0,getSize().width,getSize().height, this);
正如建议的那样,缩放图像后,将图像简单地设置为 JLabel 的图标可能会更容易,该图标已使用 BorderLayout
添加到图像 Pane
您假设面板的大小是正确的,但事实并非如此,因为面板的布局管理器将接管。
这是多余的,因为 Swing 会在调整组件大小时自动重新绘制组件。
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e)
{
repaint();
}
});
最好的办法是将图像 Pane 拖放到滚动 Pane 中,或者重新缩放图像以动态适应 Pane 的大小。
例如...
可缩放页面
public class ComicPage {
public static void main(String[] args) {
new ComicPage();
}
public ComicPage() {
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) {
}
try {
BufferedImage page = ImageIO.read(getClass().getResource("/1346.gif"));
ComicPagePane comicPagePane = new ComicPagePane();
comicPagePane.setComicPage(page);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(comicPagePane);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (Exception exp) {
exp.printStackTrace();
}
}
});
}
public class ComicPagePane extends JPanel {
private BufferedImage comicPage;
private Image scaledInstance;
public void setComicPage(BufferedImage page) {
if (page != comicPage) {
comicPage = page;
scaledInstance = null;
repaint();
}
}
@Override
public void invalidate() {
scaledInstance = null;
super.invalidate();
}
public BufferedImage getComicPage() {
return comicPage;
}
public double getScaleFactor(int iMasterSize, int iTargetSize) {
return (double) iTargetSize / (double) iMasterSize;
}
public double getScaleFactorToFit(BufferedImage img) {
double dScale = 1d;
double dScaleWidth = getScaleFactor(img.getWidth(), getWidth());
double dScaleHeight = getScaleFactor(img.getHeight(), getHeight());
dScale = Math.min(dScaleHeight, dScaleWidth);
return dScale;
}
protected Image getScaledInstance(BufferedImage master) {
if (scaledInstance == null) {
double scaleFactor = getScaleFactorToFit(master);
System.out.println("scaleFactor = " + NumberFormat.getNumberInstance().format(scaleFactor));
// This is not the best scaling alorithm
scaledInstance = master.getScaledInstance(
(int) Math.round(master.getWidth() * scaleFactor),
(int) Math.round(master.getHeight() * scaleFactor), Image.SCALE_SMOOTH);
}
return scaledInstance;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
BufferedImage comicPage = getComicPage();
if (comicPage != null) {
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth();
int height = getHeight();
// Normally, I would put this into a background worker as this
// operation can be expensive....
Image scaledInstance = getScaledInstance(comicPage);
int x = (width - scaledInstance.getWidth(this)) / 2;
int y = (height - scaledInstance.getHeight(this)) / 2;
g2d.drawImage(scaledInstance, x, y, this);
g2d.dispose();
}
}
}
}
可滚动页面
public class ScrollableComicPage {
public static void main(String[] args) {
new ScrollableComicPage();
}
public ScrollableComicPage() {
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) {
}
try {
BufferedImage page = ImageIO.read(getClass().getResource("/1346.gif"));
ComicPagePage comicPagePane = new ComicPagePage();
comicPagePane.setComicPage(page);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(comicPagePane));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (Exception exp) {
exp.printStackTrace();
}
}
});
}
public class ComicPagePage extends JPanel {
private BufferedImage comicPage;
@Override
public Dimension getPreferredSize() {
return comicPage != null ? new Dimension(comicPage.getWidth(), comicPage.getHeight()) : new Dimension(0, 0);
}
public void setComicPage(BufferedImage page) {
if (page != comicPage) {
comicPage = page;
invalidate();
repaint();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (comicPage != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(comicPage, 0, 0, this);
g2d.dispose();
}
}
}
}
您可以阅读Java: maintaining aspect ratio of JPanel background image有关缩放技术的更多信息。
关于java - 面板内绘制的图像似乎有错误的 x,y 偏移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13166402/
问题故障解决记录 -- Java RMI Connection refused to host: x.x.x.x .... 在学习JavaRMI时,我遇到了以下情况 问题原因:可
我正在玩 Rank-N-type 并尝试输入 x x .但我发现这两个函数可以以相同的方式输入,这很不直观。 f :: (forall a b. a -> b) -> c f x = x x g ::
这个问题已经有答案了: How do you compare two version Strings in Java? (31 个回答) 已关闭 8 年前。 有谁知道如何在Java中比较两个版本字符串
这个问题已经有答案了: How do the post increment (i++) and pre increment (++i) operators work in Java? (14 个回答)
下面是带有 -n 和 -r 选项的 netstat 命令的输出,其中目标字段显示压缩地址 (127.1/16)。我想知道 netstat 命令是否有任何方法或选项可以显示整个目标 IP (127.1.
我知道要证明 : (¬ ∀ x, p x) → (∃ x, ¬ p x) 证明是: theorem : (¬ ∀ x, p x) → (∃ x, ¬ p x) := begin intro n
x * x 如何通过将其存储在“auto 变量”中来更改?我认为它应该仍然是相同的,并且我的测试表明类型、大小和值显然都是相同的。 但即使 x * x == (xx = x * x) 也是错误的。什么
假设,我们这样表达: someIQueryable.Where(x => x.SomeBoolProperty) someIQueryable.Where(x => !x.SomeBoolProper
我有一个字符串 1234X5678 我使用这个正则表达式来匹配模式 .X|..X|X. 我得到了 34X 问题是为什么我没有得到 4X 或 X5? 为什么正则表达式选择执行第二种模式? 最佳答案 这里
我的一个 friend 在面试时遇到了这个问题 找到使该函数返回真值的 x 值 function f(x) { return (x++ !== x) && (x++ === x); } 面试官
这个问题在这里已经有了答案: 10年前关闭。 Possible Duplicate: Isn't it easier to work with foo when it is represented b
我是 android 的新手,我一直在练习开发一个针对 2.2 版本的应用程序,我需要帮助了解如何将我的应用程序扩展到其他版本,即 1.x、2.3.x、3 .x 和 4.x.x,以及一些针对屏幕分辨率
为什么案例 1 给我们 :error: TypeError: x is undefined on line... //case 1 var x; x.push(x); console.log(x);
代码优先: # CASE 01 def test1(x): x += x print x l = [100] test1(l) print l CASE01 输出: [100, 100
我正在努力温习我的大计算。如果我有将所有项目移至 'i' 2 个空格右侧的函数,我有一个如下所示的公式: (n -1) + (n - 2) + (n - 3) ... (n - n) 第一次迭代我必须
给定 IP 字符串(如 x.x.x.x/x),我如何或将如何计算 IP 的范围最常见的情况可能是 198.162.1.1/24但可以是任何东西,因为法律允许的任何东西。 我要带198.162.1.1/
在我作为初学者努力编写干净的 Javascript 代码时,我最近阅读了 this article当我偶然发现这一段时,关于 JavaScript 中的命名空间: The code at the ve
我正在编写一个脚本,我希望避免污染 DOM 的其余部分,它将是一个用于收集一些基本访问者分析数据的第 3 方脚本。 我通常使用以下内容创建一个伪“命名空间”: var x = x || {}; 我正在
我尝试运行我的test_container_services.py套件,但遇到了以下问题: docker.errors.APIError:500服务器错误:内部服务器错误(“ b'{” message
是否存在这两个 if 语句会产生不同结果的情况? if(x as X != null) { // Do something } if(x is X) { // Do something } 编
我是一名优秀的程序员,十分优秀!