TL; DR 異なるDPI設定では、アプリケーションのコンポーネントが重複する可能性があります。それを取り除くには、UIを更新した後で常にコンポーネントの幅をチェックしたいと思います。質問の最後に簡単なコード。UI更新が0になった後のSpringLayoutのコンポーネントの幅
基本的な問題は、異なるDPI設定では、プログラムのさまざまな部分が最も遠くに届くということです。上位のDPIでは動的に生成されるラベル、下位のDPIでは固定幅のテキストフィールド。
私はSpringLayoutを使用して、変更可能なDPI設定に対処しています。上記の説明では、特定の設定でコンポーネントが重なってしまうという問題があります。
これを克服するために、あるコンポーネントの左端が他のコンポーネントの右端よりもさらに左にあるかどうかを調べ、スペースを増やすために10ピクセルを追加するかどうかを確認したいと考えました。
if (labelRight.getX() < (labellist.get(0).getX() + labellist.get(0).getWidth+10)){
//Use one SpringLayout setting for labelRight
} else //Use another SpringLayout setting for labelRight
生成されたコンポーネントの幅をチェックするのが問題だと思います。ユーザは、パネルコンテンツの一部を変更する異なる設定から選択することができる。 labellist
には、その領域の右端のラベルが含まれています。
私はこの問題は、幅チェック幅を示すために小さなtestprogramを作った:
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SpringLayout;
import javax.swing.UIManager;
public class testsforSO extends JFrame {
private static final long serialVersionUID = -857761460788731909L;
ArrayList<JLabel> lbls = new ArrayList<>();
int lblCount = 6;
JPanel panel = new JPanel();
SpringLayout sl_panel = new SpringLayout();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
testsforSO frame = new testsforSO();
frame.pack();
frame.setVisible(true);
frame.setSize(500, 500);
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public testsforSO() {
getContentPane().add(panel);
updateUI();
JButton incr = new JButton("Increment here!");
incr.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
for (int i=0; i<=lbls.size()-1; i++){
panel.remove(lbls.get(i));
}
lblCount++;
lbls.clear();
updateUI();
panel.repaint();
panel.revalidate();
System.out.println("Width of slimest label: " + lbls.get(0).getWidth());
System.out.println("Width of widest label : " + lbls.get(lbls.size()-1).getWidth());
}
});
panel.add(incr);
sl_panel.putConstraint(SpringLayout.NORTH, incr, 10, SpringLayout.NORTH, panel);
sl_panel.putConstraint(SpringLayout.EAST, incr, -10, SpringLayout.EAST, panel);
panel.setLayout(sl_panel);
}
private void updateUI(){
for (int i = 0; i <= lblCount; i++) {
String abc = new String();
for (int j = 0; j <= i; j++) {
abc += "xx";
}
JLabel bfrLbl = new JLabel(abc);
lbls.add(bfrLbl);
panel.add(bfrLbl);
}
for (int i = 0; i <= lbls.size() - 1; i++) {
if (i > 0)
sl_panel.putConstraint(SpringLayout.NORTH, lbls.get(i), 8, SpringLayout.SOUTH, lbls.get(i - 1));
else
sl_panel.putConstraint(SpringLayout.NORTH, lbls.get(i), 8, SpringLayout.NORTH, panel);
}
}
}
ボタンを押すと、UIが一番下にもう一つのラベルで更新されます。それに応じてSpringLayoutが適合し、パネルが再確認されます。しかし、幅の出力は0です。それはなぜですか、それに対して私は何ができますか?
sl_panel.getConstraint(SpringLayout.WIDTH, lbls.get(0)).getValue();
は、トリックを行います。