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.

Другие вопросы по тегам