SVG в Java не отображается правильно
Хорошо, у меня есть Java-программа, которая отображает некоторые тайлы, которые являются SVG, в FlowLayout. Он делает это, будучи классом ScrabbleRack и расширяя JPanel, а затем добавляя плитки JSVGCanvas к этой панели.
После этого я создал рамку и добавил панель, это. (упаковал это и показал это). При появлении панель не отображается должным образом. Он просто отображает первую плитку, а затем в пространстве, где должны отображаться остальные плитки, появляется whitearea.
Но если я изменю размер рамки на любую величину, изображение будет отображаться правильно.
public class ScrabbleRackGUI extends JPanel{
ScrabbleRack rack=new ScrabbleRack();
JSVGCanvas rackContentsImages[]=new JSVGCanvas[8];
public ScrabbleRackGUI() {
setLayout(new FlowLayout());
createComponents();
}
public void createComponents() {
//INITIALISE SOURCE IMAGES
initImages();
for (int i=0;i<rackContentsImages.length;i++){
this.add(rackContentsImages[i]);
}
}
private void initImages(){
File tempImages[]=new File[8];
for(int i=0;i<8;i++){
tempImages[i]= new File("./src/res/rackBackground.svg");
rackContentsImages[i]=new JSVGCanvas();
try {
rackContentsImages[i].setURI(tempImages[i].toURL().toString());
} catch (MalformedURLException ex) {
Logger.getLogger(ScrabbleBoardGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[])
{
JFrame frame = new JFrame("ScrabbleTest");
ScrabbleRackGUI rack= new ScrabbleRackGUI(1);
frame.add(rack);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setSize(214,70);
frame.setVisible(true);
}
}
Любые идеи о том, как я могу заставить эту панель отображаться правильно, в первый раз.
Или какой-нибудь хак, который изменит размер в конце программы.
Я использовал батик для рендеринга SVG в Java для тех, кто хочет воспроизвести эту проблему.
3 ответа
Ваша проблема может заключаться в том, что создание вашего GUI не выполняется на EDT.
Ваш главный должен выглядеть примерно так:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyWindow window = new MyWindow();
MyWindow.setVisible(true);
}
});
}
а остальная часть вашего кода в текущем main должна быть в конструкторе MyWindow.
Более подробную информацию можно найти по адресу http://leepoint.net/JavaBasics/gui/gui-commentary/guicom-main-thread.html (среди других мест)
Прежде всего, вы написали: ScrabbleRackGUI rack= new ScrabbleRackGUI(1); и у вас нет конструктора, который принимает int.
Во-вторых, вы устанавливаете FlowLayout для компонента JPanel, а JPanel по умолчанию имеет FlowLayout в качестве макета. лучше позвоните супер (); чтобы получить все преимущества JPanel.
Попробуйте запустить приложение в потоке диспетчеризации событий (EDT), как уже упоминалось другими. SwingUtilities.invokeLater(new Runnable() { // ваш код здесь}
Также вы должны установить свой URI следующим образом: setURI(f.toURI(). ToURL(). ToString()); потому что f.toURL() устарела.
Я надеюсь, что это помогает.
Это может быть связано с проблемой Batik 35922, о которой сообщалось здесь: https://issues.apache.org/bugzilla/show_bug.cgi?id=35922
Если я правильно понимаю отчет об ошибке, вы можете обойти эту проблему, добавив сначала экземпляры JSVGCanvas (и экземпляр ScrabbleRackGUI) и вызвав pack(), а затем установите URI для каждого JSVGCanvas.