Графическая программа работает на Windows, но не на Mac - PullRequest
0 голосов
/ 29 января 2019

Я написал эту программу на Java, используя Swing.Когда я запускаю это на своем Mac каждый раз, когда вызывается repaint(), создается пятьдесят новых синих точек, а старые синие точки стираются.Я провел много исследований, чтобы попытаться решить эту проблему, и мне не повезло.Затем сегодня в моем классе информатики я узнаю, что программа работает на компьютерах с Windows, которые находятся в классе.Мой вопрос: почему это так и как я могу это исправить, чтобы программа работала на моем Mac?Также на заметку, что я относительно новичок в использовании свинга в Java, поэтому мне было интересно, правильно ли я все организовываю и могу ли я что-то сделать иначе?

Это класс, в котором я рисую все в JPanel.

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Canvas;
import java.lang.Math;
import java.awt.event.*;
import javax.swing.*;
public class BarnsleyFern extends JPanel 
{
   private double newX,x=0;
   private double newY,y=0;
   public BarnsleyFern()
   {  
      ActionListener action = new ActionListener()
      {
         public void actionPerformed(ActionEvent event)
         {
            repaint();
         }
      };
      Timer timer = new Timer(100,action);
      //timer.start();
      MouseListener mouse = new MouseListener()
      {
         public void mouseClicked(MouseEvent event)
         {
            //repaint();
         }
         public void mousePressed(MouseEvent event)
         {
         }
         public void mouseReleased(MouseEvent event)
         {
         }
         public void mouseEntered(MouseEvent event)
         {
         }
         public void mouseExited(MouseEvent event)
         {
         } 
      };
      MouseMotionListener mouseMotion = new MouseMotionListener()
      {
         public void mouseDragged(MouseEvent event)   
         {
            repaint();
         }
         public void mouseMoved(MouseEvent event)
         {
            repaint();
         }
      };   
      addMouseListener(mouse);
      addMouseMotionListener(mouseMotion);
   }
   public void paintComponent(Graphics window)
   {
      Graphics2D g2d = (Graphics2D)window;
      g2d.translate(360,800);
      fern(window);
   }
   public void fern(Graphics window)
   {
      Color newColor = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
      for(int i=0;i<50;i++)
      {
         window.setColor(Color.BLUE);
         int rand = (int)(Math.random()*100);
         if(rand<1)
         {
            newX=0;
            newY=0.16*y;
         }
         else if(rand<86)
         {
            newX=0.85*x + 0.04*y;
            newY=0.85*y - 0.04*x + 1.6;
         }  
         else if(rand<93)
         {
            newX=0.20*x - 0.26*y;
            newY=0.23*x + 0.22*y + 1.6;
         }
         else
         {
            newX=0.28*y - 0.15*x;
            newY=0.26*x + 0.24*y + 0.44;
         }
         window.fillOval((int)(newX*165.364),-(int)(newY*80.014),2,2);   
         x=newX;
         y=newY;
      }
   }
}

Это класс, который устанавливает JFrame и добавляет JPanel.

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

public class BarnsleyFernRunner 
{
   public BarnsleyFernRunner()
   {
      JFrame frame = new JFrame();
      frame.setTitle("Barnsley Fern");
      frame.setSize(800,800);
      frame.setLocation(300,0);
      frame.setResizable(false);
      frame.setBackground(Color.BLACK);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setLayout(null);
      BarnsleyFern panel= new BarnsleyFern();
      panel.setSize(800,800);
      panel.setOpaque(true);
      panel.setBackground(Color.BLACK);
      frame.add(panel);

      frame.setVisible(true);
   }
   public static void main(String[] args)
   {  
      BarnsleyFernRunner runner = new BarnsleyFernRunner();
   }
}

1 Ответ

0 голосов
/ 29 января 2019

«Основной» вопрос заключается в том, что вы нарушаете требования цепочки краски ...

public void paintComponent(Graphics window)
{
   Graphics2D g2d = (Graphics2D)window;
   g2d.translate(360,800);
   fern(window);
}

Реализация super *1004* делает что-то важное, если вы не готовычтобы взять на себя эту ответственность, вы должны убедиться, что вы звоните super.paintComponent сначала

Вам не помогает ...

  frame.setSize(800,800);
  frame.setLocation(300,0);
  frame.setResizable(false);
  frame.setLayout(null);
  panel.setSize(800,800);
  panel.setOpaque(true);

Вы должны оставить значение по умолчанию BorderLayoutэто сделает вашу жизнь намного проще.

Просто обновив BarnsleyFern, чтобы переопределить getPreferredSize, вы получите гораздо более гибкое решение.Это означает, что pack окно и доступный размер контента будут являться предпочтительным размером контента, в отличие от размера окна МИНУС украшения кадра.

public class BarnsleyFern extends JPanel {
    //...
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(800, 800);
    }

На основе ...

ActionListener action = new ActionListener() {
    public void actionPerformed(ActionEvent event) {
        repaint();
    }
};
Timer timer = new Timer(100, action);
//timer.start();

Я подозреваю, что вы надеетесь получить составную краску, где свойства x / y обновляются в каждом цикле рисования.

Ну, это не сработаетпо ряду причин.Вы нашли один.Graphics является общим ресурсом, каждый компонент, окрашенный в данном цикле рисования, будет использовать один и тот же экземпляр Graphics, это означает, что вы можете получить грязные краски (и, как побочный эффект, результат, который вы, похоже, ищете)Но, как вы обнаружили, это не всегда работает.

Рисование также может происходить по ряду причин, многие из которых без вашего ведома или ведома.

Рисование должно отображать текущее состояние, но не должно изменять его.Это то, что должен делать ваш Timer.

Вам нужно разработать модель, которая будет допускать постепенное изменение каждый раз, когда Timer тикает, компонент затем будет использовать модель, чтобы просто нарисовать текущее состояние.

Я бы порекомендовал прочитать:

для получения более подробной информации

...