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

Image не отрисовывается с первого раза в JPanel

16.03.2013, 02:01. Показов 3217. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте.
Учу Java и возникли трудности с GUI. То что я пытаюсь сделать, это отрисовать пару картинок на JPanel. По задумке, 1-ая картинка отрисовывается сразу после инициализации всех компонентов, а вторая после щелчка. И потом как по принципу Toogle, с каждым щелчком отрисовывается то 1-ая, то 2-ая, снова 1-ая.... и т.д.
Но проблемма заключается в том, что картинка 1-ая не отрисовыается сразу(надо потянуть JFrame и сразу появляется). Со второй картинкой такая же проблемма. Но что самое интересное это то, что баг действует только 2 первых щелчка, а потом как по маслу... всё работает... ((

Класс фрейма
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
import java.awt.Toolkit;
 
import javax.swing.JFrame;
 
@SuppressWarnings("serial")
public class NewJFrame1 extends JFrame {
    
    public NewJFrame1() {
        
        setSize(Toolkit.getDefaultToolkit().getScreenSize().getSize().width - 250,
                Toolkit.getDefaultToolkit().getScreenSize().getSize().height - 30);
        
        setTitle("Test");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
 
    public static void main(String[] args) {
        
        NewJFrame1 frame = new NewJFrame1();
        NewJPanel panel = new NewJPanel();
 
        frame.add(panel);
    }
}
Класс панели
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
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
 
import javax.swing.JPanel;
 
@SuppressWarnings("serial")
public class NewJPanel extends JPanel {
 
    public Image img1 = Toolkit.getDefaultToolkit().getImage("res/vazovski.jpg");
    public Image img2 = Toolkit.getDefaultToolkit().getImage("res/2.jpg");
 
    public NewJPanel() {
        setBackground(new Color(0, 129, 129));
        addMouseListener(new MyMouseListener());
    }
 
        public int x = 0;
 
    public void paintComponent(Graphics g) {
 
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
 
        if ((x % 2) == 0 || (x == 0))
            g2d.drawImage(img1, 50, 50, null);
        else if ((x % 2) == 1) {
            g2d.drawImage(img2, 600, 100, 350, 500, null);
        }
    }
    
    private class MyMouseListener extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            System.out.println(e.getPoint());
            System.out.println(x);
            repaint();
            x++;
        }
    }
}
А ещё есть вопрос №2.
Допустим есть Панель 400х400. Рисую картинку1 50х50 в (0,0). Потом хочу нарисовать картинку2 50х50 в (150,150).
Как сделать так чтобы при отрисовке второй катринки, первая не стиралась? Чем пользоваться?

Исходник
PS. https://dl.dropbox.com/u/43883530/Test.rar
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.03.2013, 02:01
Ответы с готовыми решениями:

Сохранить то, что отображается на JPanel, в Image (и восстановить обратно)
Как сделать так, чтобы то, что отображается в объекте-наследнике JPanel в объект Image. После я...

Image помещенный в Scrollbox не полностью отрисовывается
Здравствуйте, форумчане! Помогите, пожалуйста разобраться с такой ситуацией: Есть у меня на форме...

Не отрисовывается таблица для первого элемента из массива
Здравствуйте, задача в том что бы отобразить на странице несколько свежих материалов в обратном...

Добавление JPanel на JPanel, не отображаются те, которые добавлены сверху
Здравствуйте. У меня есть панель fon на которой у меня картинка с фоном и 15 панелей на которых...

3
512 / 454 / 119
Регистрация: 17.02.2012
Сообщений: 1,032
Записей в блоге: 1
16.03.2013, 11:00 2
первая ошибка - вы делаете сначала фрейм видимым, а после на него что то ложите. Из-за этого первая проблема - надо потянуть JFrame и сразу появляется
вторая ошибка - класс NewJPanel - строка 41-42 - поменяйте местами, сначала увеличьте переменную, а после перерисуйте.
P.S.
можно обойтись без переменно x

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
privat boolean flag = true;
public void paintComponent(Graphics g) {
 
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
 
        if (flag)
            g2d.drawImage(img1, 50, 50, null);
        else {
            g2d.drawImage(img2, 600, 100, 350, 500, null);
        }
    }
private class MyMouseListener extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            System.out.println(e.getPoint());
            flag = !flag;
            repaint();         
        }
    }


Добавлено через 1 минуту
Цитата Сообщение от VanOxy Посмотреть сообщение
Как сделать так чтобы при отрисовке второй катринки, первая не стиралась?
рисовать сразу обе
0
1 / 1 / 1
Регистрация: 26.04.2012
Сообщений: 10
18.03.2013, 00:34  [ТС] 3
Переделал - поставил setVisible(true) в main(), уже лучше - не приходиться растягивать Frame, чтобы хотя бы увидеть Background панели. И флаг поставил...
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public NewJFrame1() {
        
        setSize(Toolkit.getDefaultToolkit().getScreenSize().getSize().width - 250,
                Toolkit.getDefaultToolkit().getScreenSize().getSize().height - 30);
        
        setTitle("Test de dessin les images avc les clicks");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
 
    public static void main(String[] args) {
        
        NewJFrame1 frame = new NewJFrame1();
        NewJPanel panel = new NewJPanel();
 
        frame.add(panel);
        frame.setVisible(true);
    }

Но проблемма остаётся, 1ая каритнка по идее должна отрисовываться сразу её не видно. Щелчок - отрисовка 2ой картинки (её не происходит, точнее происходит но надо "потянуть"), щёлчок и вот появляется первая картинка без "плясок"...
Так что проблемма остаётся...

Добавлено через 5 часов 9 минут
И всё-таки метод "научного тыка" великая вещь... Ну и API Java естественно
Решение проблеммы крылось в добавлении метода checkImage() в конструктор панели.
Так как в API нашёл что некоторым прогам надо подготовить картинку для показа.
Source: "An application must use the prepareImage method to force the loading of an image."
Что ж, тогда будем готовить... Сказано - сделано.
Кликните здесь для просмотра всего текста
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
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
 
import javax.swing.JPanel;
 
@SuppressWarnings("serial")
public class NewJPanel extends JPanel {
 
    public Image img1 = Toolkit.getDefaultToolkit().getImage("res/vazovski.jpg");
    public Image img2 = Toolkit.getDefaultToolkit().getImage("res/2.jpg");
 
    private boolean flag = true;    
    
    public NewJPanel() {
 
        setBackground(new Color(0, 129, 129));
        addMouseListener(new MyMouseListener());
        checkImage(img1, this);
        checkImage(img2, this); 
    }
 
    public void paintComponent(Graphics g) {
 
        super.paintComponent(g);
        
        if (flag){
            g.drawImage(img1, 50, 50, null);
        }
        else {
            g.drawImage(img2, 600, 100, 350, 500, null);
        }
    }
 
    private class MyMouseListener extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            System.out.println(e.getPoint());
            flag = !flag;
            repaint();
        }
    }
}

И кстате заметьте, что для отрисовки использовал Graphics g, а не Graphics2D g2d. В чём собственно разница, так как результат идентичный?

PS.Но решение одной проблеммы, породило другую, на горе моего пытливого разума...
Создал вторую Панельку с FlowLayout'ом и пытаюсь по нажатию мыши добавлять панельки меньшего размера с картинкой. Та же проблемма что и в начале приходится "тянуть" JFrame после добавления каждой панельки, а то не видно добавляются они или нет...
Помучаюсь ещё немного и если не получиться то выложу код с мольбой о помощи... Хотя если получится, то тоже выложу

Добавлено через 20 часов 14 минут
Ничего не получается...
Куда только я не пытался приткнуть метод checkImage(), не отображаются картинки пока не "потянешь".
Кто знает в чём проблема?
Фрейм :
Кликните здесь для просмотра всего текста
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
import java.awt.Toolkit;
 
import javax.swing.JFrame;
 
@SuppressWarnings("serial")
public class NewJFrame1 extends JFrame {
    
    public NewJFrame1() {
        
        setSize(Toolkit.getDefaultToolkit().getScreenSize().getSize().width - 250,
                Toolkit.getDefaultToolkit().getScreenSize().getSize().height - 30);
    
        setTitle("Test");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
 
    public static void main(String[] args) {
        
        NewJFrame1 frame = new NewJFrame1();
        MyPanel myPanel = new MyPanel();
 
        frame.add(myPanel);
        frame.setVisible(true);
    }
}

Панель :
Кликните здесь для просмотра всего текста
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
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
 
import javax.swing.JPanel;
 
public class MyPanel extends JPanel {
 
    private Image img2 = Toolkit.getDefaultToolkit().getImage(
            "res/vazovski.jpg");
    private ArrayList<JPanel> cars = new ArrayList<JPanel>();
    private JPanel adversary = new JPanel();
 
    public MyPanel() {
        init();
    }
 
    private void init() {
        addMouseListener(new MyMouseListener());
        createMiniPanels();
        adversary.setPreferredSize(new Dimension(800, 200));
        adversary.setBackground(new Color(55, 129, 180));
        add(adversary);
    }
 
    private void createMiniPanels() {
        // создаём панельки в которых будут рисоваться картинки
        for (int i = 0; i < 24; i++) {
            cars.add(new Card());
            cars.get(i).setPreferredSize(new Dimension(70, 100));
        }
    }
 
    private class Card extends JPanel {
 
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(img2, 0, 0, 70, 100, null);
        }
    }
 
    private int x = 0;
    private class MyMouseListener extends MouseAdapter {
        // с каждым кликом добавляется панелька на другую панель
        public void mouseClicked(MouseEvent e) {
            adversary.add(cars.get(x));
            adversary.repaint();
            x++;
        }
    }
}


Добавлено через 5 часов 39 минут
Проблема решена. Всё заключалось в том, что после mouseClicked() надо было не repaint(), а updateUI().
Java
1
2
3
4
5
 public void mouseClicked(MouseEvent e) {
            adversary.add(cards.get(x));
            adversary.updateUI();
            x++;
        }
И ещё до того, при инициации (или инициализации...??? ) мини панелек под рисунки надо всё-таки проверить рисунок, то есть checkImage(). Для этого добавил конструктор, что бы при их создании (панелек) туда можно было запихивать лубую картинку... В общем вот что получилось :
Кликните здесь для просмотра всего текста
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
public class MyPanel extends JPanel {
 
    private Image img2 = Toolkit.getDefaultToolkit().getImage(
            "res/vazovski.jpg");
    private ArrayList<JPanel> cards = new ArrayList<JPanel>();
    private JPanel adversary = new JPanel();
 
    public MyPanel() {
        init();
    }
 
    private void init() {
        addMouseListener(new MyMouseListener());
        createMiniPanels();
        adversary.setPreferredSize(new Dimension(800, 200));
        adversary.setBackground(new Color(55, 129, 180));
        add(adversary);
    }
 
    private void createMiniPanels() {
        // создаём панельки в которых будут рисоваться картинки
        for (int i = 0; i < 24; i++) {
            cards.add(new Card(img2));
            cards.get(i).setPreferredSize(new Dimension(70, 100));
        }
    }
 
    private class Card extends JPanel {
        
        public Card(Image img){
            checkImage(img2, this);
        }
 
        public void paint(Graphics g) {
            super.paint(g);
            g.drawImage(img2, 0, 0, 70, 100, null);
        }
    }
 
    private int x = 0;
    private class MyMouseListener extends MouseAdapter {
        // с каждым кликом добавляется панелька на другую панель
        public void mouseClicked(MouseEvent e) {
            adversary.add(cards.get(x));
            adversary.updateUI();
            x++;
        }
    }
}

А на счёт самой первой проблемы с NewJPanel, так там вообще можно поступить вот так :
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public NewJPanel() {
 
        setBackground(new Color(0, 129, 129));
        addMouseListener(new MyMouseListener());
        //checkImage(img1, this);
        //checkImage(img2, this);       
    }
 
    public void paintComponent(Graphics g) {
 
        super.paintComponent(g);
        
        if (flag){
            g.drawImage(img1, 50, 50, null);
        }
        else {
            g.drawImage(img2, 600, 100, 350, 500, null);
        }
        this.updateUI();
    }
И не надо никаких checkImage().
Если у кого есть другие варианты реализации, то пожалуйста выкладывайте мне будет очень интересно. А так же буду рад критике...
0
tao1x
18.03.2013, 23:30 4
Цитата Сообщение от VanOxy Посмотреть сообщение
Проблема решена. Всё заключалось в том, что после mouseClicked() надо было не repaint(), а updateUI().
спасибо, помогло
18.03.2013, 23:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.03.2013, 23:30
Помогаю со студенческими работами здесь

Как правильно задать размер JPanel чтобы JFrame при pack() сжимался до размеров JPanel
Подскажите как правильно задать размер JPanel чтобы JFrame при pack() сжимался до размеров JPanel,...

Удаление JPanel кнопкой на этом же JPanel
Есть JPanel объекты, которые представляют собой панельки с какой - то информацией, на них есть...

Не запускается с первого раза
Всем привет! Возникла следующая проблема, при запуске компьютера не загорается монитор, все кулера...

с первого раза не включаеться
после того как видеокарту поставил комп начал рандомно включаться то на 1раз то на 3 то на 6 ...


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

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