Форум программистов, компьютерный форум, киберфорум
Java: GUI, графика
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
1

Изображения стандартных компонентов

06.07.2014, 14:55. Показов 925. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет.

Столкнулся с небольшой проблемой в ходе разработки приложения. Суть приложения такова - есть панель Toolkit с набором компонентов, доступных для использования (перетаскивания) и панель рабочего пространства, куда элементы перетаскиваются.

Процесс перетаскивания реализую через MouseMotionListener интерфейс.
Java
1
2
3
            public void mouseDragged(MouseEvent e) {
                but.setBounds(e.getX(), e.getY(), but.getWidth(), but.getHeight());
            }
То есть когда я нажал на компонент и тащу его по экрану - его положение должно автоматически меняться. Проблема заключается в том, что идет неправильная калькуляция пикселей, то есть идет сдвиг, сейчас объясню почему.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    private static JFrame frm;
    private static JPanel space;
    private static  JButton but;
 
    public static void main(String[] args) {
        frm = new JFrame("Test");
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        init();
 
        frm.setSize(300, 300);
        frm.setVisible(true);
    }
 
    private static void init() {
        space = new JPanel();
 
        but = new JButton("Button");
        addMouseAdapter(but);
 
        space.add(but);
        frm.getContentPane().add(BorderLayout.EAST, space);
    }
 
    private static void addMouseAdapter(JComponent comp) {
        MouseAdapter adapter = new MouseAdapter() {
            boolean canMove = false;
 
            @Override
            public void mouseDragged(MouseEvent e) {
                but.setBounds(e.getX(), e.getY(), but.getWidth(), but.getHeight());
            }
 
            @Override
            public void mousePressed(MouseEvent e) {
                if(e.getX() > but.getX() && e.getX() < but.getX() + but.getWidth() &&
                        e.getY() > but.getY() && e.getY() < but.getY() + but.getHeight()) {
                    canMove = true;
                }
            }
 
            @Override
            public void mouseReleased(MouseEvent e) {
                frm.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                canMove = false;
            }
        };
 
        comp.addMouseListener(adapter);
        comp.addMouseMotionListener(adapter);
    }
Вот исполняемый код. Было бы идеально реализовать MouseMotionListener интерфейс в панеле, когда при любом движении мы бы получали верные пиксели - панельные. Если так и сделаем, то все бы ничего, но кнопка является интерактивным компонентом, так что она обрабатывает свои собственные события.

Если мы добавим кнопку как слушателя событий мыши - это сработает, но результат будет отвратным - отображение на экране будет двоиться, кнопка будет отпрыгивать от курсора при нажатии и так далее. Можете убедиться скомпилировав и запустив код, приведенный выше...

Я придумал довольно простое решение - создать панель, установить такой размер, чтобы туда могла поместиться только кнопка (аналогичный размер), переопределить метод paintComponent() и при каждой прорисовке панели рисовать изображение (иконку) кнопки. Когда я перетащу кнопку на рабочую панель, я получу событие EnterEvent и на месте панели размещу самую натуральную кнопку...

Возможно, это довольно глупое решение, но пока ничего лучше в голову не пришло. Если вы знаете, как решить проблему с перемещением кнопки с корректным отображением - буду рад выслушать.

А пока вопрос такой - как получить иконку кнопки?
P.S. button.getIcon() возвращает null.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.07.2014, 14:55
Ответы с готовыми решениями:

Разработка приложений с использованием стандартных и дополнительных компонентов. Динамическое создание компонентов.
Здравствуйте! Помогите мне, пожалуйста. Условие задачи состоит в следующем: из списка выбираю...

Просмотреть листинг стандартных компонентов
Здравствуйте! Интерисует такой вопрос. Есть у нас стандартная палитра компонентов, к примеру...

Переопределение свойств у стандартных компонентов
Создал подкласс кнопки. Как сделать что бы при нажатии на кнопку DrawEllipse перерисовался только с...

Использование стандартных компонентов stl
Помогите реализовать задачу с помощью stl Даны натуральное число n, действительные числа a1, ... ,...

10
Форумчанин
5955 / 4190 / 405
Регистрация: 28.12.2013
Сообщений: 24,134
06.07.2014, 18:23 2
Цитата Сообщение от Freedomen Посмотреть сообщение
Было бы идеально реализовать MouseMotionListener интерфейс в панеле, когда при любом движении мы бы получали верные пиксели - панельные
так можно же прикрепить слушатель к панели.

Добавлено через 12 минут
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
 
public class Main extends JFrame {
 
    public static void main(String[] args) {
        Main m = new Main();
        m.init();
    }
        
        static JPanel panel = new JPanel();
 
        private static final long serialVersionUID = 1L;
        
        public void init() {
            
            initFrame();    
            initPanel();
 
        }
        
        private void initFrame(){
            setSize(500, 500);
            setLocationRelativeTo(null);
            setVisible(true);
            setDefaultCloseOperation(3);
            setResizable(false);    
            setLayout(null);
        }
        
        private void initPanel(){
            
            panel.setLayout(null);
            panel.addMouseMotionListener(new MouseMotionListener(){
 
                @Override
                public void mouseDragged(MouseEvent e) {
                    
                    System.out.println(e.getX());
                    System.out.println(e.getY());
                    System.out.println("\n");
                    
                }
 
                @Override
                public void mouseMoved(MouseEvent e) {
                    // TODO Auto-generated method stub
                    
                }
                
            });
            panel.setPreferredSize(new Dimension(100,100));
            panel.setBackground(java.awt.Color.BLACK);
            panel.setBounds(0, 0, 250, 250);
            add(panel);
            
        }
 
}
или я не то понял
0
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
06.07.2014, 19:10  [ТС] 3
Дальше в тексте я объясняю, почему не получится. Кнопка - интерактивный компонент, она сама является источником событий, и у нее свои слушатели. То есть если мы попытаемся добавить слушателя в панель, потом в панель добавить кнопку, то нажав и переталкивая кнопку по панели, ничего не получится, если пиксели события принадлежат кнопке, причину выше написал. Получается, мы никак не сможем узнать - тащит ли программист кнопку, если будем слушать панель.

Я расписал оптимальный вариант, но для этого нужны иконки, а как их получить программно - я не разобрался.
0
Форумчанин
5955 / 4190 / 405
Регистрация: 28.12.2013
Сообщений: 24,134
06.07.2014, 19:32 4
тоесть ты хочешь с 1 панели перетащить элемент в другую?А что если сделать прозрачную панель и перетаскивать элементы по ней?
Забавная задачка попробую сегодня.
0
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
06.07.2014, 19:54  [ТС] 5
У компонентов из инструментария есть переходное состояние - смена овнера. Когда мы выходим за рамки панели инструментов - фрейм становится слушателем, потом при заходе на основное пространство слушатель переходит к ворк спейсу, другие компоненты удаляют слушателя. С этим проблем нет. Но мне нужны иконки...
0
Форумчанин
5955 / 4190 / 405
Регистрация: 28.12.2013
Сообщений: 24,134
06.07.2014, 19:58 6
Цитата Сообщение от Freedomen Посмотреть сообщение
Но мне нужны иконки...
вроде бы их надо добавить чтоб небыло null,либо назначить другой UI манагер.
0
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
06.07.2014, 20:01  [ТС] 7
Да я уже пытался схитрить, но иконки где-то же хранятся. Вот мне бы источник, иначе придется магию использовать, aka своя интерпретация... xD
0
Форумчанин
5955 / 4190 / 405
Регистрация: 28.12.2013
Сообщений: 24,134
06.07.2014, 23:33 8
в принципе,кнопка может быть просто прямоугольником с градиентом,так же как и менюбар
Не думаю что ява скрывает иконку после вызова метода гетикон.

Добавлено через 2 часа 59 минут
в исходниках явки конструктор по умолчанию дает параметр иконки null
0
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
07.07.2014, 01:34  [ТС] 9
Конечно. Потому что на разных ОС разные стили. Этим вообще не должен компонент заниматься, это стилевой менеджер. Но где он берет иконки - надо это узнать...
0
Форумчанин
5955 / 4190 / 405
Регистрация: 28.12.2013
Сообщений: 24,134
07.07.2014, 01:53 10
забавная проблема,хотя для моей работы и не нужная

Просерчил исходники,что-то зацепов пока не вижу на иконку.
0
61 / 61 / 19
Регистрация: 06.09.2013
Сообщений: 236
Записей в блоге: 1
07.07.2014, 22:23  [ТС] 11
В общем, пошел другим путем. Прорисовка переталкивания фигур вышла накладной - нужно определять верные пиксели относительно сразу двух панелей, вычислять относительное положение компонента и от сюда получать пиксели верные. К тому же во время переходного состояния компонент должен обрисовывываться сразу в 3х контейнерах, поэтому пришлось добавлять в каждый контейнер компонент, который "растет" по мере переталкивания, а потом и вовсе удаляется. Пусть это и не занимает много памяти, но трата все же идет больше, чем можно было ожидать. Ну и естественно такой подход не дает никакой гибкости.

В раздумьях был и пришел к такому варианту. Есть панель инструментов - она представляет собой кастомный лист (список JLabel - иконка и текст). При выборе элемента - его изображение переносится в Clipboard - буфер, в котором хранится выдранный из списка элемент. Как только элемент попал в буфер - можно тыкнуть на любую область в workspace панели и установится изображение кнопки (не оригинальное). Буфер очищается, выдранный элемент перестает быть выбранным. Компоненты на рабочей панеле можно переталкивать. Но это не все. Когда нужно посмотреть - как будет выглядеть кнопка на этом месте - все компоненты удаляются, сериализуются (для восстановления) и на их местах появляются самые настоящие кнопки. Их двигать нельзя - они самостоятельные компоненты. Когда нужно изменить позиции - возвращается к рабочему состоянию, удаляем кнопки и на их местах появляются десермализованные компоненты.

Пока есть один нюанс - как при крепить маленькую иконку к курсору? Конечно, можно сделать кастомный курсор, но наверняка есть способ это сделать через API. Буду рад помощи. P.S. Рад бы и сам порыскать API, но приходится временно вечера коротать с одним телефоном и медленным интернетом.
0
07.07.2014, 22:23
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.07.2014, 22:23
Помогаю со студенческими работами здесь

Разработка приложений с использованием стандартных компонентов.
Даны последовательность из n целых чисел и целое число a. Найти номер первого вхождения a в...

Модификация стандартных компонентов использующих TStrings
Уважаемые программисты объясните как сделать так чтобы для компоненты TCheckListBox дополнительно к...

UDP чат без использования стандартных компонентов
Здраствуйте! Срочно нужен UDP чат но БЕЗ ИСПОЛЬЗОВАНИЯ стандартных компонентов... Кто может...

UDP чат без использования стандартных компонентов
Здраствуйте! Срочно нужен UDP чат но БЕЗ ИСПОЛЬЗОВАНИЯ стандартных компонентов... Кто может...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru