java获取系统dpi_如何使用Java“正确”检测显示的DPI?

我有以下应用程序绘制规则:

public class Rule extends JComponent

{

public static final long serialVersionUID=26362862L;

// public static final int INCH=Toolkit.getDefaultToolkit().getScreenResolution();

public static final int INCH=(int)(Toolkit.getDefaultToolkit().getScreenResolution()*1.15); // Auto adjust this 1.15 ?

public static final int HORIZONTAL=0;

public static final int VERTICAL=1;

public static final int SIZE=35;

public int orientation;

public boolean isMetric;

private int increment;

private int units;

// private Color rule_color=new Color(0,135,235);

private Color rule_color=new Color(120,170,230);

static JFrame frame=new JFrame("Rule");

static Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize(); // 1600 x 1200 , 1024 x 768

static JPanel rulerPanel=new JPanel(new BorderLayout());

public Rule(int o,boolean m)

{

orientation=o;

isMetric=m;

setIncrementAndUnits();

}

public void setIsMetric(boolean isMetric)

{

this.isMetric=isMetric;

setIncrementAndUnits();

repaint();

}

private void setIncrementAndUnits()

{

if (isMetric)

{

units=(int)((double)INCH/(double)2.54); // dots per centimeter

increment=units;

}

else

{

units=INCH;

increment=units/2;

}

}

public boolean isMetric() { return this.isMetric; }

public int getIncrement() { return increment; }

public void setPreferredHeight(int ph) { setPreferredSize(new Dimension(SIZE,ph)); }

public void setPreferredWidth(int pw) { setPreferredSize(new Dimension(pw,SIZE)); }

public void setColor(Color color) { rule_color=color; }

public void paintComponent(Graphics g)

{

Rectangle drawHere=g.getClipBounds();

// Fill clipping area with blue-gray.

g.setColor(rule_color);

g.fillRect(drawHere.x,drawHere.y,drawHere.width,drawHere.height);

// Do the ruler labels in a small font that's black.

g.setFont(new Font("SansSerif",Font.PLAIN,10));

g.setColor(Color.black);

// Some vars we need.

int end=0;

int start=0;

int tickLength=0;

String text=null;

// Use clipping bounds to calculate first tick and last tick location.

if (orientation==HORIZONTAL)

{

start=(drawHere.x/increment)*increment;

end=(((drawHere.x+drawHere.width)/increment)+1)*increment;

}

else

{

start=(drawHere.y/increment)*increment;

end=(((drawHere.y+drawHere.height)/increment)+1)*increment;

}

// Make a special case of 0 to display the number within the rule and draw a units label.

if (start==0)

{

text=Integer.toString(0)+(isMetric?" cm":" in");

tickLength=10;

if (orientation==HORIZONTAL)

{

g.drawLine(0,SIZE-1,0,SIZE-tickLength-1);

g.drawString(text,2,21);

}

else

{

g.drawLine(SIZE-1,0,SIZE-tickLength-1,0);

g.drawString(text,9,10);

}

text=null;

start=increment;

}

// ticks and labels

for (int i=start;i

{

if (i%units==0)

{

tickLength=10;

text=Integer.toString(i/units);

}

else

{

tickLength=5;

text=null;

}

if (tickLength!=0)

{

if (orientation==HORIZONTAL)

{

g.drawLine(i,SIZE-1,i,SIZE-tickLength-1);

if (text!=null) g.drawString(text,i-3,21);

}

else

{

g.drawLine(SIZE-1,i,SIZE-tickLength-1,i);

if (text!=null) g.drawString(text,9,i+3);

}

}

}

}

// Create the GUI and show it. For thread safety, this method should be invoked from the event-dispatching thread.

static void createAndShowGUI()

{

rulerPanel.setPreferredSize(new Dimension(570,78));

Rule cmView=new Rule(Rule.HORIZONTAL,true);

int H=35;

cmView.setPreferredHeight(H);

cmView.setColor(new Color(128,200,235));

JScrollPane cmScrollPane=new JScrollPane();

cmScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));

cmScrollPane.setColumnHeaderView(cmView);

rulerPanel.add("North",cmScrollPane);

Rule inchView=new Rule(Rule.HORIZONTAL,true);

inchView.setPreferredHeight(H);

inchView.setColor(new Color(168,200,235)); //238,238,238

inchView.setIsMetric(false);

JScrollPane inchScrollPane=new JScrollPane();

inchScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));

inchScrollPane.setColumnHeaderView(inchView);

rulerPanel.add("South",inchScrollPane);

frame.getContentPane().add(rulerPanel);

frame.addWindowListener(new WindowAdapter()

{

public void windowActivated(WindowEvent e) { }

public void windowClosed(WindowEvent e) { }

public void windowClosing(WindowEvent e) { System.exit(0); }

public void windowDeactivated(WindowEvent e) { }

public void windowDeiconified(WindowEvent e) { rulerPanel.repaint(); }

public void windowGainedFocus(WindowEvent e) { rulerPanel.repaint(); }

public void windowIconified(WindowEvent e) { }

public void windowLostFocus(WindowEvent e) { }

public void windowOpening(WindowEvent e) { rulerPanel.repaint(); }

public void windowOpened(WindowEvent e) { }

public void windowResized(WindowEvent e) { rulerPanel.repaint(); }

public void windowStateChanged(WindowEvent e) { rulerPanel.repaint(); }

});

frame.pack();

frame.setBounds((screenSize.width-rulerPanel.getWidth())/2,(screenSize.height-rulerPanel.getHeight())/2-19,rulerPanel.getWidth()+20,rulerPanel.getHeight()+38);

frame.setVisible(true);

}

public static void main(String[] args)

{

// Schedule a job for the event-dispatching thread : creating and showing this application's GUI.

SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } });

}

}

它在我的旧17“和20”显示器上工作正常,现在我注意到我的新27“液晶显示器,这是不准确的,所以我必须改变第4行更准确,不是Toolkit.getDefaultToolkit(). getScreenResolution()应该得到准确的DPI,为什么不正确,对于我的应用程序在其他具有不同显示尺寸和DPI的机器上,如何自动调整1.15我手动放入?

PS:不仅我的Java应用程序的DPI不准确,而且当我看到Windows 7上的其他几个应用程序,如paint.exe或者paint.net时,他们的英寸和厘米也是正确的.你可以在你的机器上试试.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值