4

I'm successfully rendering a polygon shaped window. However, I would like to outline it with a thin stroke.

Is it possible to outline a shaped window in Java?

Here's my working code, I'm using the componentResized method to set the shape for the window. However, if there is any other way to go in order to get the outline, both for when the Tab-Window is minimized and when the Tab-Window is maximized, please help.

//LongTab.java
//Desktop Tab

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;

public class LongTab extends JWindow implements MouseListener{

  static LongTab t;
  Boolean isVisible = false;
  final static BasicStroke stroke = new BasicStroke(2.0f);
  GeneralPath path;

  public LongTab(){
    addMouseListener(this);
    setSize(500, 1080);

    addComponentListener(new ComponentAdapter() {
      @Override
      public void componentResized(ComponentEvent e){
        Polygon polygon = new Polygon();
        polygon = new Polygon();
        polygon.addPoint(40, 1080);
        polygon.addPoint(40, 700);
        polygon.addPoint(20, 690);
        polygon.addPoint(20, 400);
        polygon.addPoint(40, 390);
        polygon.addPoint(40, 0);
        polygon.addPoint(500, 0);
        polygon.addPoint(500, 1080);

        path = new GeneralPath();
        path.append(polygon, true);
        setShape(path);
      }
    });

    setSize(40, 1080);
    setLocation(1880, 0);
  } 

  public void mouseClicked (MouseEvent me) {
    if(!isVisible) {
      isVisible=true;
      t.setSize(400, 1080);
      t.setLocation(1520, 0);
      return;
    }
    if(isVisible) {
      isVisible=false;
      t.setSize(40, 1080);
      t.setLocation(1880, 0);
    }
    return;
  }

  public void mouseEntered (MouseEvent me) {
  }

  public void mousePressed (MouseEvent me) {
  }

  public void mouseReleased (MouseEvent me) {
  } 

  public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);     
    g2.setStroke(stroke);
    //if(!isVisible)
    //g2.draw(path);
    //repaint();
  }

  public void mouseExited (MouseEvent me) {
  }  

  public static void main (String[] args){
    SwingUtilities.invokeLater(new Runnable(){
      @Override
      public void run() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();

        //If shaped windows aren't supported, exit.
        if (!gd.isWindowTranslucencySupported(PERPIXEL_TRANSPARENT)) {
          System.err.println("Shaped windows are not supported");
          System.exit(0);
        } else {
          t = new LongTab();
          t.setVisible(true)
        }
      }
    });
  }
}
amaidment
  • 6,942
  • 5
  • 52
  • 88
aubreybourke
  • 439
  • 1
  • 5
  • 17

3 Answers3

1

I modified your code to display shaped window outline.

    //LongTab.java
//Desktop Tab

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsDevice.WindowTranslucency;
import java.awt.GraphicsEnvironment;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;

import javax.swing.JFrame;

public class LongTab extends JFrame{

private Polygon polygon;

public LongTab() {
    setSize(500, 720);
    setLocation(10, 10);

    setUndecorated(true);


    polygon = new Polygon();
    polygon = new Polygon();
    polygon.addPoint(40, 720);
    polygon.addPoint(40, 700);
    polygon.addPoint(20, 690);
    polygon.addPoint(20, 400);
    polygon.addPoint(40, 390);
    polygon.addPoint(40, 20);
    polygon.addPoint(500, 20);
    polygon.addPoint(500, 720);

    GeneralPath path = new GeneralPath();
    path.append(polygon, true);
    setShape(path);
}

public void paint(Graphics g) {
    super.paint(g);

    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setStroke(new BasicStroke(2.0f));
    g2.setColor(Color.RED);
    g2.draw(polygon);
}

public static void main(String[] args) {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice gd = ge.getDefaultScreenDevice();

    // If shaped windows aren't supported, exit.
    if (!gd.isWindowTranslucencySupported(WindowTranslucency.PERPIXEL_TRANSLUCENT)) {
        System.err.println("Shaped windows are not supported");
        System.exit(0);
    } else {
        new LongTab().setVisible(true);
    }
}
}

Note that I also made the polygon somewhat smaller, because I do not have HD screen to fit your original polygon.

Lastly I removed event handling code, because I could not understand what you are trying to do with mouse clicks. With this working starting point, you can add your event handling code again.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Hakan Serce
  • 11,198
  • 3
  • 29
  • 48
  • Thanks Andrew, but couple of problems with your code. It compiles fine, but when running it with java 7, I see no outline of the polygon at all! I am going to try java 6 now. Secondly, the main reason the event handling code is there is because it facilitates opening and closing of the tab on a widescreen monitor (1920x1080). Later I will code in some controls into the open Tab. – aubreybourke May 22 '12 at 14:22
  • First of all, Andrew just edited, it is me who answered your question :)) This code is Java 7 code, it shouldn't even compile with Java 6. What happens when you directly run the code I pasted above, I mean with no modification? I ask this because it runs and shows the window with a red outline. If the code works this way, then we can start talking about the other parts of your code. – Hakan Serce May 22 '12 at 15:17
  • Sorry for taking so long! Yes, using Java6. Its complaining about the the AWTUtilities class missing which uses a different API to the Java7 release. – aubreybourke May 23 '12 at 18:38
  • The code you posted is Java 7 code, but if you want to use Java 6 now, check here: http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html#6u10 – Hakan Serce May 23 '12 at 18:47
1

Ok, added the import, and took out the Translucency validation. When I run this Java6 code the red outline displays for <1 sec, then the outline vanishes! Not sure why?

//LongTab.java
//Desktop Tab

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
//import java.awt.GraphicsDevice.WindowTranslucency;
import java.awt.GraphicsEnvironment;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;

import javax.swing.JFrame;
import com.sun.awt.AWTUtilities.*;

public class LongTab extends JFrame{

private Polygon polygon;

public LongTab() {
    setSize(500, 720);
    setLocation(10, 10);

    setUndecorated(true);


    polygon = new Polygon();
    polygon = new Polygon();
    polygon.addPoint(40, 720);
    polygon.addPoint(40, 700);
    polygon.addPoint(20, 690);
    polygon.addPoint(20, 400);
    polygon.addPoint(40, 390);
    polygon.addPoint(40, 20);
    polygon.addPoint(500, 20);
    polygon.addPoint(500, 720);

    GeneralPath path = new GeneralPath();
    path.append(polygon, true);
    com.sun.awt.AWTUtilities.setWindowShape(this, path);
}

public void paint(Graphics g) {
    super.paint(g);

    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setStroke(new BasicStroke(2.0f));
    g2.setColor(Color.RED);
    g2.draw(polygon);
}

public static void main(String[] args) {
    //GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    //GraphicsDevice gd = ge.getDefaultScreenDevice();

    // If shaped windows aren't supported, exit.
    //if (!gd.isWindowTranslucencySupported(WindowTranslucency.PERPIXEL_TRANSLUCENT)) {
    //    System.err.println("Shaped windows are not supported");
    //    System.exit(0);
    //} else {
        new LongTab().setVisible(true);
    //}
}
}
aubreybourke
  • 439
  • 1
  • 5
  • 17
0

I managed to figure out how to solve the problem with Java 6. It seems just simply taking out the antialias line in my paint method solves the graphic rendering glitch, where the outline isnt clean enough. Here's the fully working code...

Regards Aubrey.

 //LongTab.java
 //Desktop Tab

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.awt.geom.*;
    import com.sun.awt.AWTUtilities.*;

    public class LongTab extends JWindow implements MouseListener{

    static LongTab t;
    Boolean isVisible = false;

    GeneralPath closed;

    final static BasicStroke stroke = new BasicStroke(2.0f);
    GeneralPath path;


    //Constructor
    public LongTab(){


        addMouseListener(this);
        setSize(500, 1080);


    addComponentListener(new ComponentAdapter() {
    @Override
    public void componentResized(ComponentEvent e){
    Polygon polygon = new Polygon();
    polygon = new Polygon();

    polygon.addPoint(40, 1080);
    polygon.addPoint(40, 700);

    polygon.addPoint(20, 690);
    polygon.addPoint(20, 400);
    polygon.addPoint(40, 390);

    polygon.addPoint(40, 0);
    polygon.addPoint(500, 0);
    polygon.addPoint(500, 1080);



    path = new GeneralPath();
    path.append(polygon, true);
    //setShape(path);
    com.sun.awt.AWTUtilities.setWindowShape(t, path);

    }});

    setSize(40, 1080);
    setLocation(1880, 0);

    }//end of constructor.

     public void mouseClicked (MouseEvent me) {


      if(!isVisible){
      isVisible=true;
      t.setSize(400, 1080);
      t.setLocation(1520, 0);

    return;
    }
      if(isVisible){
      isVisible=false;
      t.setSize(40, 1080);
      t.setLocation(1880, 0);
      }
      return;

    }
     public void mouseEntered (MouseEvent me) {}
     public void mousePressed (MouseEvent me) {}
     public void mouseReleased (MouseEvent me) {} 
     public void mouseExited (MouseEvent me) {}  

     public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;

        //antialias commented out to fix outline glitch.
        //g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g2.setStroke(stroke);

    g2.drawLine(40, 1080, 40, 700);
    g2.drawLine(40, 700, 20, 690);
    g2.drawLine(20, 690, 20, 400);
    g2.drawLine(20, 400, 40,390);
    g2.drawLine(40, 390, 40, 0);



    }
    public static void main (String[] args){

                t = new LongTab();
                t.setVisible(true);
    }

}
aubreybourke
  • 439
  • 1
  • 5
  • 17