LINUX.ORG.RU

8
Всего сообщений: 35

Java desktop GUI framework?

Меня очень раздражает Swing, но альтернатив ему не вижу. Может быть, что-то упускаю?

Смотрю в сторону JavaFX, но совсем не ясно что с ним будет через пару лет.

P.S. Будет приложение выглядеть нативно под каждой платформой или нет - без разницы.

 , ,

SaBo ()

SweetHome3d поломаный UI

Ищу приложение в котором могу нормально и просто спроэктировать дизайн дома\комнаты.

Поиск вывел меня на SweetHome3d.

Но UI у приложения полностью поломан (судя по всему приложение использует Swing) любое движение вышкой приводит к черноте экрана, наложению эллементов друг на друга и т.д. https://imgur.com/a/ejoHqBn

Пробовал по Gnome\Xfce Xorg\Wayland ...

Кто подскажет как можно поправить?

 , , , ,

letitbe ()

Java GUI

На чём сейчас принято делать gui в java? Смотрел в сторону swing и fx, если я правильно понял, то на fx давно забили?

 , , , ,

chrisred ()

На чем склепать GUI?

Нужно склепать не очень сложный гуй, вопрос - на чем? С нативными gtk && qt (читай: С/C++) делов не имел, возиться с ними лишний раз не хотелось бы. Более быстрые и простые варианты приветствуются.

Как там дела у java/swing? А у python/tkinter? Или - на крайняк - electron?

На чем пишет гуй лоровец?

 , ,

SuoiCat ()

На какой бы тайлинг переехать с awesome, или как решить проблему с менюшками IDEA?

Собственно, все время пользовался awesome и в ус не дул, но по долгу работы стала актуальна замена Emacs на IDEA.

Но тут я увидел супер «фичу» не знаю кого именно awesome или java-шного гуи-тулкита, но каждое меню превращается в отдельное окошко и даже в floating-режиме улетает в верхний левый угол.

Возможно, я просто рукожоп и что то делаю не так.

 , , , ,

nihirash ()

Java и desktop

Я конечно понимаю, что Java на десктоп ориентированна меньше, чем на другие области применения, однако отсутствие возможности централизованно управлять стилем отображения и особенно шрифтами swing/javafx на мой взгляд какое-то недоразумение.

Подход применяемый в gtk и qt позволяет работать в разных приложениях, отображаемых в едином стиле. Изменил глобальные настройки отображения - все подхватили по умолчанию. Если приложению требуется какая-либо кастомизация, разработчик реализует ее.

Если речь идет о swing, то подобное поведение наблюдается только при использовании GTKLookAndFeel. И ведь можно даже задать его использование по умолчанию с помощью Dswing.defaultlaf в _JAVA_OPTIONS.

Малину портят приложения, которые принудительно устанавливают стиль отображения, например DBVis. GTKLookAndFeel не доступен принципиально, выбирать приходится между Metal и несколькими убогими темами в самом приложении. Хорошо, будь по вашему, беру Metal. Но что это за убожество вместо шрифтов? Само приложение позволяет поменять шрифты только для таблиц и редактора, так что приходится наслаждаться мелкими для моего разрешения, но полужирными шрифтами в меню. Неужели нет никакой возможности это исправить?

С javafx как я понимаю все еще хуже. Нет никакого аналога Dswing.defaultlaf. Хочешь чтобы твое приложение выглядело стильно? Интегрируй в него темку. Хочешь, чтобы все javafx приложения выглядели стильно? Мечтай, это невозможно.

Ну как так то? Доколе? Если я в чем-то не права и просто не умею готовить джаву, научите.

Пример: https://ibb.co/e8Y6e7

 , , ,

totik ()

Openbox, шрифты в Java приложениях

Отвратительные шрифты у жабы в коробке, вообще без сглаживания. Как сделать? Эту строчку в ./profile добавлял:

export _JAVA_OPTIONS="-Dawt.useSystemAAFontSettings=on"

На этой же системе стоит XFCE, там шрифты в java-приложениях выглядят замечательно.

 , , ,

matrasa ()

swig(c++ -> python) ошибка линковки

code.cpp:

#include "code.h"
#include <iostream>

void foobar(void){
	std::cout<<"foobar()"<<std::endl;
}
code.h:
#ifndef _code
#define _code
int nx=8;
int ny=8;
int nz=8;
float dx=0.1;
float dy=0.1;
float dz=0.1;
void foobar(void);
#endif
code.i:
%module code
%{
#include "code.h"
%}
%include "code.h"
Компилирую:
g++ -std=c++11 -c -fPIC code.cpp
swig -c++ -python code.i
g++ -std=c++11 -c -fPIC code_wrap.cxx  -I/usr/include/python2.7 -I/usr/lib/python2.7
g++ -std=c++11 -shared -Wl,-soname,_code.so -o _code.so code.o code_wrap.o
и получаю ошибку линковки:
code_wrap.o:(.data+0x188): multiple definition of `nx'
code.o:(.data+0x0): first defined here
code_wrap.o:(.data+0x18c): multiple definition of `ny'
code.o:(.data+0x4): first defined here
code_wrap.o:(.data+0x190): multiple definition of `nz'
code.o:(.data+0x8): first defined here
code_wrap.o:(.data+0x194): multiple definition of `dx'
code.o:(.data+0xc): first defined here
code_wrap.o:(.data+0x198): multiple definition of `dy'
code.o:(.data+0x10): first defined here
code_wrap.o:(.data+0x19c): multiple definition of `dz'
code.o:(.data+0x14): first defined here
Какого хрена? И что тогда эта зараза не рушается на multiple definition of `void foobar(void)`?

 , ,

thunar ()

Из-за swing-окон иногда пропадает win-tab

Привет!
Есть проблема:
Я не могу вычленить, почему, однако иногда при создании Swing-окошек (java) гном перестает реагировать на альт-таб или вин-таб. При этом, открытие дашборда (винкей) работает без проблем.
Кто-нибудь сталкивался? Про это есть баг?
Спасибо.

 ,

takino ()

Закрытие приложения Swing+JavaFX

Привет! Столкнулся с такой проблемой.

Есть приложение, написано на JavaFX, но при этом есть кусок Swing-а, которое прикручено через SwingNode. Exit сделан так:

Platform.exit()
Т.е закрывается только FX треды всякие, а свинг продолжает жить, что логично - он же в EDT вроде как. В связи с этим вопрос, а как мне Правильно закрывать этот самый SwingNode? В самом SwingNode у меня лежит GLJPanel. Про вариант
System.exit(0)
знаю. Есть какой-нибудь способ другой? Знаю, что можно поставить
node.setDefaultCloseOperation(WindowClosingProtocol.WindowClosingMode.DISPOSE_ON_CLOSE);
Но это не помогает, все равно при закрытии приложения что-то висит в фоне. Прошу совета, так как сам не слишком разбираюсь в том, как с Swing правильно работать) Заранее спасибо за советы.

 , ,

aarexer ()

Выложил свой java-проект на github

https://github.com/Ivana-/Liscript-GUI-Java-Swing

Если у кого будет желание конструктивно покритиковать, с интересом почитаю. А критиковать там есть что, ибо мне самому не нравится как многое сделано, но как могу на текущий момент.

 , , ,

Ivana ()

Swing - подсветка синтаксиса. Варианты реализации?

Господа, это снова я, только не бейте пожалуйста :) И все еще на Swing, да. Потом буду на пробовать JavaFX, честно.

Хочу простого - многострочное текстовое поле с подсветкой синтаксиса собственного языка. По минимуму - выделение цветом ключевых слов, строк внутри кавычек, числовых констант, и подсветка парных скобок от текущего положения курсора. По максимуму - нет предела совершенству Да, реализация пока на Swing - компонентах, потом планируется вариант на JavaFX. Беглый просмотр инета дал 3 общих варианта:

1) Готовые библиотеки где все из коробки. В принципе не против, только смущает их тяжеловесность, наличие ненужного функционала (мне только свой язык подсвечивать). Но зато там бывает и нумерация строк, и подсветка текущей строки, и свертка-развертка по плюсикам и т.п., что интригует. И конечно надо выбрать библиотеку (например, RSyntaxTextArea) и умудриться подключить её к проекту.

2) Свои написания с нуля на JEditorPane, Document и EditorKit.

3) Вариант 2, но на JTextComponent, java.text.AttributedString и еще каких-то непонятных пока компонентах.

Что посоветуете, доктора?

 , , ,

Ivana ()

Дошлифовать Swing GUI desktop application

Хотел написать для Андроида, но решил протестировать и доделать рабочий вариант для компа. Первый блин на Java, выбор пал на Swing поскольку инет завален ссылками по нему, а с JavaFX связываться не решился. Собственно, от интерфейса требуется минимализм, надежность и кроссплатформенность. Это РЕПЛ (рид-эвал-принт-лууп) одного языка, в нижнем окне набираются команды, в верхнем отображается результат (как он будет готов). Здесь только UI оболочка, парсинг и вычисление вынес в отдельные классы, здесь стоят заглушки. Собственно, хотел узнать - это так вообще делается? Прямо класс Main наследуется от JFrame и вся UI логика прописывается в нем? Или выделять отдельный класс для этого? Как сделать изменение мышкой относительных размеров окон ввода и вывода (сейчас они у меня в таблице, высота одинакова)? Хорошо ли из отдельного потока выполнения изменять элементы UI перед завершением потока? Если лучше делать это в основном потоке, то как организовать красивый надежный коллбэк по завершению потока вычислений? Ну и вообще, любая конструктивная критика/рекомендации приветствуются.

package com.company;

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

public class Main extends JFrame {

    private static JTextArea textArea;
    private static JEditorPane textAreaIn;
    private static DefaultListModel<InterThread> threadListModel =
            new DefaultListModel<InterThread> ();
    private static JList threadList = new JList<InterThread> (threadListModel);
    private static JToolBar buttonsPanel;

    public Main() {
        super("GUI REPL");

        textArea = new JTextArea(5, 30);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        textArea.setFont(new Font("Courier New", Font.PLAIN, 12));

        JScrollPane scrollPane = new JScrollPane(textArea);
        scrollPane.setPreferredSize(new Dimension(500, 300));
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        final StyleContext sctextAreaIn = new StyleContext();
        final DefaultStyledDocument doctextAreaIn = new DefaultStyledDocument(sctextAreaIn);
        textAreaIn = new JTextPane(doctextAreaIn);
        final Style style0 = sctextAreaIn.addStyle("emptyStyle", null);
        style0.addAttribute(StyleConstants.FontSize, 12);
        style0.addAttribute(StyleConstants.FontFamily, "Courier New");
        doctextAreaIn.setParagraphAttributes(0, 1, style0, true);

        JScrollPane scrollPaneIn = new JScrollPane(textAreaIn);
        scrollPaneIn.setPreferredSize(new Dimension(500, 300));
        scrollPaneIn.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        threadList.setCellRenderer(new DefaultListCellRenderer() {
            @Override
            public Component getListCellRendererComponent(
                    JList<?> list, Object value, int index, boolean isSelected,
                    boolean cellHasFocus) {
                Component renderer = super.getListCellRendererComponent(
                        list, value, index, isSelected, cellHasFocus);
                if (renderer instanceof JLabel && value instanceof Thread) {
                    ((JLabel) renderer).setText(((Thread) value).getName());
                }
                return renderer;
            }
        });
        threadList.setFont(new Font("Courier New", Font.BOLD, 20));

        JScrollPane scrollPaneThreads = new JScrollPane(threadList);
        scrollPaneThreads.setPreferredSize(new Dimension(150, 300));
        scrollPaneThreads.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);


        JLabel lastLoadFileNameLabel = new JLabel();

        Action sendUserInputAction = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                sendUserInput();
            }
        };
        JButton sendUserInput = new JButton();
        sendUserInput.setAction(sendUserInputAction);
        sendUserInput.setText("send (CTRL+ENTER)");
        sendUserInput.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
                .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.CTRL_MASK)
                        , "sendUserInputAction");
        sendUserInput.getActionMap().put("sendUserInputAction", sendUserInputAction);


        Action loadFileAction = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser fileopen = new JFileChooser();
                fileopen.setFileFilter(new FileNameExtensionFilter("TXT files", "txt"));
                int ret = fileopen.showDialog(getParent(), "Выберите файл скрипта");
                if (ret == JFileChooser.APPROVE_OPTION) {
                    File file = fileopen.getSelectedFile();
                    try {
                        String s = new Scanner(file).useDelimiter("\\Z").next();
                        lastLoadFileNameLabel.setText(file.getAbsolutePath());
                        startNewThread(false, s);
                    } catch (IOException ex) {
                        cout(true, "problem accessing file " + file.getAbsolutePath());
                    }
                }
            }
        };
        JButton loadFile = new JButton();
        loadFile.setAction(loadFileAction);
        loadFile.setText("load file");

        Action reloadFileAction = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String fileAbsolutePath = lastLoadFileNameLabel.getText();
                try {
                    File file = new File(fileAbsolutePath);
                    String s = new Scanner(file).useDelimiter("\\Z").next();
                    startNewThread(false, s);
                } catch (IOException ex) {
                    cout(true, ex.getLocalizedMessage());
                }
            }
        };
        JButton reloadFile = new JButton();
        reloadFile.setAction(reloadFileAction);
        reloadFile.setText("reload file");

        Action showActiveThreadsAction = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
                ThreadGroup parent;
                while ((parent = threadGroup.getParent()) != null) {
                    threadGroup = parent;
                    Thread[] threadList = new Thread[threadGroup.activeCount()];
                    threadGroup.enumerate(threadList);
                    for (Thread thread : threadList)
                        cout(true, thread.getThreadGroup().getName()
                                + " " + thread.getPriority()
                                + " " + thread.getName());
                }
            }
        };
        JButton showActiveThreads = new JButton();
        showActiveThreads.setAction(showActiveThreadsAction);
        showActiveThreads.setText("active threads");


        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(scrollPaneThreads, BorderLayout.EAST);

        JPanel textsPanel = new JPanel(new GridLayout(2,1));
        textsPanel.add(scrollPane);
        textsPanel.add(scrollPaneIn);
        getContentPane().add(textsPanel, BorderLayout.CENTER);

        sendUserInput.setDefaultCapable(true);

        buttonsPanel = new JToolBar(SwingConstants.VERTICAL);
        buttonsPanel.add(sendUserInput);
        buttonsPanel.addSeparator();
        buttonsPanel.add(loadFile);
        buttonsPanel.add(reloadFile);
        buttonsPanel.add(showActiveThreads);
        getContentPane().add(buttonsPanel, BorderLayout.WEST);
        getContentPane().add(lastLoadFileNameLabel, BorderLayout.SOUTH);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public class Read {
        public Object read(String s) { return "(" + s + ")"; }
    }

    public class Eval {
        Eval() {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                //e.printStackTrace();
            }
        }
        public Object eval(Object o) { return "evaluated: " + o.toString(); }
    }

    public class InterThread extends Thread {
        public String expression;
        public boolean showEcho;

        InterThread(boolean _showEcho, String _exp) { showEcho = _showEcho; expression = _exp; }

        public void run() {
            try {
                Object ro = new Read().read(expression);
                if (showEcho) cout(true, ro.toString());
                cout(true, new Eval().eval(ro).toString());
            } catch (Throwable e) {
                cout(true, e.toString());
                Thread.currentThread().interrupt();
            }
            textAreaIn.setText("");
            if (threadListModel.contains(this))
                threadListModel.remove(threadListModel.indexOf(this));

            for (Component c : buttonsPanel.getComponents()) {
                if (c.getClass().getSimpleName().equals("InterThreadJButton")) {
                    if (((InterThreadJButton) c).thread.equals(this))
                        buttonsPanel.remove(c);
                }
            }
            buttonsPanel.updateUI(); // .revalidate();
        }
    }

    class InterThreadJButton extends JButton {
        public InterThread thread;

        InterThreadJButton(InterThread t) {
            thread = t;

            Action interruptAction = new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    cout(true, "interrupt");
                    thread.interrupt();
                    cout(true, thread.getName());
                }
            };
            this.setAction(interruptAction);
            this.setText(thread.getName());
        }
    }

    public void startNewThread(boolean showEcho, String exp) {
        if (exp == null || exp.trim().isEmpty()) return;

        InterThread it = new InterThread(showEcho, exp);
        it.start();
        threadListModel.addElement(it);
        buttonsPanel.add(new InterThreadJButton(it));
    }

    public static void cout(boolean ln, String s) {
        if (s == null) return;
        if (ln) textArea.append(s + "\n"); else textArea.append(s);
        textArea.setCaretPosition(textArea.getDocument().getLength());
    }

    public void sendUserInput() {
        startNewThread(true, textAreaIn.getText());
    }

    //--------------------------------- MAIN -----------------------------

    public void run() throws FileNotFoundException {
        cout(true, "Lets begin");
    }

    public static void main(String[] args) throws FileNotFoundException {
        Main application = new Main();
        application.setVisible(true);
        application.pack();
        application.run();
    }
}

 , ,

Ivana ()

java, ненависть, дефолтный внешний вид (gtk)

решил я в свою игру писаную на libGDX добавить диалог. Ну реализовал интерфейс(если правильно понял как это называется, неважно сейчас), под андроид запилил нативный. И стал вопрос десктопа. Погуглил, прочитал про Swing. Подумал что это то что нужно, мне же простой диалог(вы уверены что хотите выйти с игры) нужно было сделать. Написал такой код

try {
    UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
}
catch (Exception e) {
    //Exception handle
}

//

Object[] options = {"Yes, please",
        "No, thanks",
        "No eggs, no ham!"};

int n = JOptionPane.showOptionDialog(f,
        "Would you like some green eggs to go "
                + "with that ham?",
        "A Silly Question",
        JOptionPane.YES_NO_CANCEL_OPTION,
        JOptionPane.QUESTION_MESSAGE,
        null,
        options,
        options[2]);

Компилирую это и получаю

Error parsing gtk-icon-sizes string: ''
Иду в гугл, узнаю в чем проблема, дальше редактирую свою тему(Numix, одна из стандартных тем в xubuntu) выполняя следующее:
in <YOUR THEME>/gtk-2.0/gtkrc:
gtk-icon-sizes =
"panel-menu=24,24:panel=20,20:gtk-button=18,18:gtk-large-toolbar=24,24"

Заработало, выглядит почти красиво. Но теперь собственно вопрос. А ЭТО ВООБЩЕ НОРМАЛЬНО? Такое поведение на одной из стандартных тем в xubutnu. Этот тупой Swing валится из-за того что не нашел какую-то строку? А вариант реализовать некое дефолтное знание в таком случае не судьба? В общем это долбаная джава меня достала. Сначала тупая idea почему-то решила загрузить i7 на ~50% на несколько минут, то прозрачные окна, то просто отвратительная графика(А ведь я не дизайнер, я пользуюсь простенькой xfce и не хочу каких-то красивых эффектов). Но поскольку ничего лучшего нет((Хочу плакать и умирать) то задам вопрос.

А что мне собственно делать в этой конкретной ситуации? Может убрать к чертям этот диалог из игры на десктопе(Я про эту игру)(все равно многие закрывают просто кликнув по крестику, а не через Esc). Или может убрать вот эту строчку

UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");

И использовать джавашный(крайне убогий) стиль? Или swing это просто неудачный выбор и есть что-то годное?

 , ,

abs ()

Как связать Gui и обработку введенной информации?

Доброго времени суток. Столкнулся с проблемой. Пусть у меня есть Gui, с textField, по нажатию кнопки я считываю то, что в textField и хочу отдавать это обработчику, а обработчик - отдельный класс в программе. Как мне связать Gui и обработку?Потому что сейчас Gui живет отдельно в своем Thread-е, а обработчик в своем, как организовать пересылку? Пробовал static переменные, пробовал get-ры, но это все не то. Прошу помощи.

Пользуюсь Swing.

Заранее спасибо!

 , ,

aarexer ()

Не отображаются кнопки на форме

Всем привет! Возник вопрос, почему в таком коде у меня не отображаются кнопки?

import javax.swing.*;
import java.awt.*;

public class MainWindow extends JFrame
{
    private JButton buttonOne;
    private JButton buttonTwo;

    MainWindow()
    {
        super("Main Window");

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(300, 200);

        setLocationRelativeTo(null);

        setLayout(new FlowLayout());

        buttonOne  = new JButton("Первая кнопка");
        buttonTwo  = new JButton("Вторая кнопка");

        buttonOne.setBackground(Color.CYAN);

        add(buttonOne);
        add(buttonTwo);

        setVisible(true);

    }
}

Само окно создается, но на него ничего не наносится. Почему так?Заранее спасибо!

 ,

aarexer ()

Кто-нибудь использовал Griffon?

Поделитесь впечатлениями и подводными камнями разработки с помощью сабжа.

 ,

Vultaron ()

JavaFX для динамически-создаваемого интерфейса

Есть задумка переделать гуй к одной программе. Набор виджетов там будет меняться в зависимости от входных данных. Кроме того, там будет довольно навороченная таблица.
Вопросы:
1) Насколько я знаю, JavaFX хороша своим декларативным описанием. Если строить гуи в стиле swing - вручную компановать виджеты и т.д. будет ли серьезный профит в скорости разработки и простоте сопровождения от JavaFX?
2) Насколько JavaFX прожорливее swing?
3) Насколько хороша JavaFX в плане локализации в случае декларативного описания?

 , ,

cab ()

Посоветуйте книгу, в которой описан полный цикл разработки ПО с GUI.

Есть ли что-то похожее, где сначала проектируется а потом через тестирование разрабатывается гуи приложение? Без разницы, это qt или swing, или что там нынче под линкусом используют?

 , , , ,

Ubuntu ()

При добавлении PopupMenu компонент забирает все ивенты от мыши

Есть у меня JTabbedPane, у которого задан кастомный TabComponent. У JTabbedPane реализован MouseListener, в котором реализовано таскание вкладок. Если в TabComponent задать попап меню методом setComponentPopupMenu, то когда мышь находится на этом компоненте - сигналы от неё идут компоненту, а не JTabbedPane, как требуется. Как с этим бороться? Меню нужно

 ,

OldWiseCat ()