我的程序有问题。每当我更改屏幕分辨率时,我的图像就会开始移动到位置之外。有关如何使我的图像保持在同一位置的任何建议,即使我更改为任何其他分辨率?
p2 = new JPanel();
p2.setLayout(new FlowLayout());
ImageIcon img2 = new ImageIcon("C:\\Drum\\Invisible4.png");
jbtn2 = new JLabel(img2);
p2.add(jbtn2);
add(jbtn2);
jbtn2.setSize(jbtn2.getPreferredSize());
jbtn2.setLocation(140, 380);
答案 0 :(得分:1)
我更愿意一直尝试在框架的边界内工作,从长远来看,它会让生活变得更加轻松。
Swing已开始设计为与LayoutManager
一起使用,这意味着Swing更新其组件并传达这些更改的方式基于LayoutManager
s(或多或少)的使用。
以下示例使用来自Java: maintaining aspect ratio of JPanel background image的片段来缩放图像,并使用PropertionalLayoutManager
来设计,不仅可以尝试缩放大小,还可以根据大小调整组件的位置。父容器。
此处演示的PropertionalLayoutManager
将尝试围绕父容器的中心布置组件。你可以改变它,但它看起来很奇怪 - 恕我直言
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager2;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.WeakHashMap;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Drums {
protected static BufferedImage SYMBOL;
protected static BufferedImage DRUM;
public static void main(String[] args) {
new Drums();
}
public Drums() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new PropertionalLayoutManager(400, 400));
add(new Symbol(), new PropertionalConstraint(0f, 0));
add(new Symbol(), new PropertionalConstraint(0.67f, 0));
add(new Symbol(), new PropertionalConstraint(0f, 0.4675f));
add(new Symbol(), new PropertionalConstraint(0.67f, 0.4675f));
add(new Drum(), new PropertionalConstraint(0.205f, 0.1f));
add(new Drum(), new PropertionalConstraint(0.5f, 0.1f));
add(new Drum(), new PropertionalConstraint(0f, 0.33f));
add(new Drum(), new PropertionalConstraint(0.705f, 0.33f));
}
}
public class PropertionalConstraint {
private float x;
private float y;
public PropertionalConstraint(float x, float y) {
this.x = x;
this.y = y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
}
public class PropertionalLayoutManager implements LayoutManager2 {
private Map<Component, PropertionalConstraint> constraints;
private Dimension defaultSize;
public PropertionalLayoutManager(int defaultWidth, int defaultHeight) {
constraints = new WeakHashMap<>(25);
defaultSize = new Dimension(defaultWidth, defaultHeight);
}
@Override
public void addLayoutComponent(Component comp, Object constraint) {
if (constraint instanceof PropertionalConstraint) {
constraints.put(comp, ((PropertionalConstraint) constraint));
}
}
@Override
public Dimension maximumLayoutSize(Container target) {
return preferredLayoutSize(target);
}
@Override
public float getLayoutAlignmentX(Container target) {
return 0.5f;
}
@Override
public float getLayoutAlignmentY(Container target) {
return 0.5f;
}
@Override
public void invalidateLayout(Container target) {
}
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
constraints.remove(comp);
}
@Override
public Dimension preferredLayoutSize(Container parent) {
return defaultSize;
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return preferredLayoutSize(parent);
}
@Override
public void layoutContainer(Container parent) {
int width = parent.getWidth();
int height = parent.getHeight();
double dScaleWidth = getScaleFactor(defaultSize.width, width);
double dScaleHeight = getScaleFactor(defaultSize.height, height);
double scaleSize = Math.min(dScaleHeight, dScaleWidth);
int minRange = Math.min(width, height);
if (width > 0 && height > 0) {
int maxY = 0;
int maxX = 0;
for (Component comp : parent.getComponents()) {
PropertionalConstraint p = constraints.get(comp);
if (p != null) {
Dimension prefSize = comp.getPreferredSize();
prefSize.width *= scaleSize;
prefSize.height *= scaleSize;
int x = Math.round(minRange * p.getX());
int y = Math.round(minRange * p.getY());
comp.setBounds(x, y, prefSize.width, prefSize.height);
maxX = Math.max(maxX, x + prefSize.width);
maxY = Math.max(maxY, y + prefSize.height);
} else {
comp.setBounds(0, 0, 0, 0);
}
}
for (Component comp : parent.getComponents()) {
System.out.println("maxX = " + maxX);
System.out.println("maxY = " + maxY);
if (comp.getWidth() > 0 && comp.getHeight() > 0) {
int x = ((width - maxX) / 2) + comp.getX();
int y = ((height - maxY) / 2) + comp.getY();
comp.setLocation(x, y);
}
}
} else {
for (Component comp : parent.getComponents()) {
comp.setBounds(0, 0, 0, 0);
}
}
}
}
public abstract class AbstractKitPiecePane extends JPanel {
private BufferedImage scaled;
public AbstractKitPiecePane() {
setOpaque(false);
}
public abstract BufferedImage getKitImage();
@Override
public Dimension getPreferredSize() {
return new Dimension(getKitImage().getWidth(), getKitImage().getHeight());
}
@Override
public void invalidate() {
super.invalidate();
if (getWidth() > 0 && getHeight() > 0) {
scaled = getScaledInstanceToFit(getKitImage(), getSize());
} else {
scaled = null;
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (scaled != null) {
int x = (getWidth() - scaled.getWidth()) / 2;
int y = (getHeight() - scaled.getHeight()) / 2;
g.drawImage(scaled, x, y, this);
}
}
}
public class Drum extends AbstractKitPiecePane {
@Override
public BufferedImage getKitImage() {
return DRUM;
}
}
public class Symbol extends AbstractKitPiecePane {
@Override
public BufferedImage getKitImage() {
return SYMBOL;
}
}
protected static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {
BufferedImage imgScale = img;
int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);
if (dScaleFactor <= 1.0d) {
imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
} else {
imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
}
return imgScale;
}
protected static BufferedImage getScaledDownInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint) {
// System.out.println("Scale down...");
int type = (img.getTransparency() == Transparency.OPAQUE)
? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
if (targetHeight > 0 || targetWidth > 0) {
int w, h;
w = img.getWidth();
h = img.getHeight();
do {
if (w > targetWidth) {
w /= 2;
if (w < targetWidth) {
w = targetWidth;
}
}
if (h > targetHeight) {
h /= 2;
if (h < targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
} while (w != targetWidth || h != targetHeight);
} else {
ret = new BufferedImage(1, 1, type);
}
return ret;
}
protected static BufferedImage getScaledUpInstance(BufferedImage img,
int targetWidth,
int targetHeight,
Object hint) {
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage ret = (BufferedImage) img;
int w, h;
w = img.getWidth();
h = img.getHeight();
do {
if (w < targetWidth) {
w *= 2;
if (w > targetWidth) {
w = targetWidth;
}
}
if (h < targetHeight) {
h *= 2;
if (h > targetHeight) {
h = targetHeight;
}
}
BufferedImage tmp = new BufferedImage(w, h, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
g2.drawImage(ret, 0, 0, w, h, null);
g2.dispose();
ret = tmp;
tmp = null;
} while (w != targetWidth || h != targetHeight);
return ret;
}
public static BufferedImage getScaledInstanceToFit(BufferedImage img, Dimension size) {
double scaleFactor = getScaleFactorToFit(img, size);
return getScaledInstance(img, scaleFactor);
}
public static double getScaleFactorToFit(BufferedImage img, Dimension size) {
double dScale = 1;
if (img != null) {
int imageWidth = img.getWidth();
int imageHeight = img.getHeight();
dScale = getScaleFactorToFit(new Dimension(imageWidth, imageHeight), size);
}
return dScale;
}
public static double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
public static double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = 1;
if (iMasterSize > iTargetSize) {
dScale = (double) iTargetSize / (double) iMasterSize;
} else {
dScale = (double) iTargetSize / (double) iMasterSize;
}
return dScale;
}
static {
try {
SYMBOL = ImageIO.read(new File("Symbol.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
try {
DRUM = ImageIO.read(new File("Drum.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
程序中使用的图像,供您享受。它们位于运行程序的同一目录中
答案 1 :(得分:0)
创建“正常”屏幕大小与当前屏幕大小的百分比/比率,并将其乘以pos。例如,您使用的屏幕尺寸是400x600
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
double widthRat = width/600
double heightRat = height/400
然后
jbtn2.setLocation(140*widthRat, 380*heightRat);
这样说屏幕尺寸加倍到1200x800 widthRat将= 2并且位置增加一倍。这是一个草率的例子,但提出了想法
答案 2 :(得分:0)
我更喜欢使用绝对布局。以下是适合您的代码。
Toolkit toolkit=Toolkit.getDefaultToolkit();
JPanel1.setSize(toolkit.getScreenSize().width, toolkit.getScreenSize().height);
int w=toolkit.getScreenSize().width;
int h=toolkit.getScreenSize().height;
JPanel1.setBounds(0, 0, w, h);
此代码将获取您计算机的当前分辨率...