Search code examples
javaswingpaintcomponent

DrawLine in Java Swing


Main idea is - when values the of the slider are growing, more lines are dividing equal parts of the component and don’t cross the lines of polygon (like it’s in upper left corner of the picture). I want to do this with all the corners but now I only did it with one of them.

Can someone tell me what I need to change to get my lines to 1/3 of Width?

My values are good for 1/2 but not for 1/3, n is a variable for slider.

enter image description here

My code:

import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Mariusz extends JFrame {

    private int n = 5;
    private Color kolor = Color.RED;

    MyComponent komponent = null;

    private class MyComponent extends JComponent
    {
        protected void paintComponent (Graphics grafika)
        {
            grafika.setColor(kolor);
            grafika.drawLine(getWidth() * 1/3, 0, 0, getHeight() * 1/3);
            grafika.drawLine(0, getHeight() * 1/3, getWidth() * 1/3, getHeight());
            grafika.drawLine(getWidth() * 1/3, getHeight(),getWidth(), getHeight() * 1/3);
            grafika.drawLine(getWidth(), getHeight() * 1/3, getWidth() * 1/3, 0);

            for (int i = 0; i < n ; i++)
            {
                if (i <= n / 3)
                {
                    grafika.drawLine(getWidth() * i /n, 0, getWidth() * i /n, (getHeight() - getHeight() * 2/3 ) -  getHeight() * i / n); //lewy gorny
                    grafika.drawLine(  getWidth() * i / n,(getHeight() - getHeight() * 2/3 ) +  getHeight() * i / n + getHeight() *1/3, getWidth() * i / n, getHeight() );
                }
                if (i > n / 3)
                {
                    grafika.drawLine(getWidth() * i / n   , 0, getWidth() * i /n,   getHeight() * 2 * i /n / 3   - getHeight() * 1 /3  );
                }
            }
        }
    }

    public Mariusz(String string) 
    {
        super(string);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Toolkit kit = Toolkit.getDefaultToolkit();
        Dimension d = kit.getScreenSize();
        setBounds( d.width / 4, d.height / 4, d.width / 2, d.height / 2);

        add (komponent = new MyComponent());

        JPanel panel = new JPanel(new BorderLayout());
        add(panel,BorderLayout.SOUTH);

        final JSlider slider = new  JSlider(3,40,n);
        slider.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                // TODO Auto-generated method stub
                n = slider.getValue();
                komponent.repaint();

            }
        });
        panel.add(slider);

        setVisible(true);
    }

    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub
        EventQueue.invokeLater(new  Runnable() {
            public void run() {
                new Mariusz("triangles");
            }
        });

    }
}

Solution

  • Your approach is ad-hoc and I cant follow that it will suceed in other measures (4/5 etc).

    Heres an approach thats based on similar triangles:

    starting from the upper right and working backwards:

    h1/h2=(2*w/3)/(2*w/3-(1/n)*(2*w/3))
    

    thus

    h2=h1/(.....)
    

    where h1=h/3.

    Converting this to code

        double f=2./3, f2=1-f;
    
        g2.setColor(Color.blue);
    
        for (int i=n-1; i>-1; i--)
        {
          grafika.drawLine(getWidth() * (n-i) / n, 0, getWidth() * (n-i)/n,  
            (int)((getHeight()/ 3)/(f/(f-1.*i/n))) );
        }
    

    For the upper left we work the same way but with factor f2:

    g2.setColor(Color.green);
    
        for (int i=0; i<n; i++)
        {
            grafika.drawLine(getWidth() * i / n   , 0, getWidth() * i /n,   (int)((getHeight()/ 3)/(f2/(f2-1.*i/n))) );
        }
    

    The same for the lower left:

    g2.setColor(Color.magenta);
    
        for (int i=0; i<n; i++)
        {
          grafika.drawLine(getWidth() * i / n   , getHeight()-(int)((2*getHeight()/ 3)/(f2/(f2-1.*i/n))), getWidth() * i /n,   getHeight() );
        }
    

    and lower right

    g2.setColor(Color.black);
    
        for (int i=n-1; i>-1; i--)
        {
          grafika.drawLine(getWidth() * (n-i) / n   , getHeight()-(int)((2*getHeight()/ 3)/(f/(f-1.*i/n))), getWidth() * (n-i) /n,  getHeight()  );
        }
    

    If you want a 4/5 measure for example you would have to change f=4./5 and all the 2*getHeight()/3 to 4*getHeight()/5(getHeight()/3 to getHeight()/5 etc).