look - setOpaque() en java
motif look and feel java (2)
Como se explica aquí , setOpaque no hace lo que uno pensaría que es, y esa falla se hace evidente en Nimbus. La otra respuesta que se refiere al color alfa es la forma correcta de lograr lo que desea.
¿Alguien puede explicar por qué Nimbius trata el setOpaque () de manera diferente que otros LaF de Java? Está rompiendo mi código porque los componentes que normalmente son transparentes ya no lo son.
EDITAR: El problema parece tratar solo con JTextAreas (que es lo que necesito) o componentes similares.
EDITAR EDITAR: Esta es una pantalla de la aplicación real. Al aplicar la solución de trashgod, el fondo aún no se muestra.
EDITAR EDITAR EDITAR:
Intenté la sugerencia de trashgod de anular la pintura (). Trabajé duro durante horas y no pude lograr que funcionara. Pude mostrar el fondo, pero JinternalFrame no se pudo mover, cambiar de tamaño y tener su texto seleccionado. Al llamar a super.paint (g) no se pudo resolver la solución. ¿Hay alguna manera fácil de hacer esto que me podría estar perdiendo?
He tomado un nuevo enfoque a esto. Dentro de JInternalFrame está JLayeredPane.
Capa 0 - JLabel
Capa 1 - JTextArea
Cuando el JInternalFrame se mueve o cambia de tamaño:
- Se vuelve invisible
- Toma una captura de pantalla de dónde estaba en el contenedor que contiene
- Pinta el JLabel con la imagen que tomó
- Se vuelve visible de nuevo.
Ya que no pude obtener el JInternalFrame para ser transparente en absoluto. Simulé su transparencia. El único problema es que hay una gran cantidad de gastos generales asociados a esto. ¿Alguna idea?
package newpackage;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
/**
* Example of how to create a transparent internal frame.
* @author dvargo
*/
public class TransparentInternalFrame extends JInternalFrame {
JLayeredPane container;
/**
* Defualt constructor to set the frame up
* @param container The container for the frame
* @param opacity The opacity of the frame
*/
public TransparentInternalFrame(JLayeredPane container, int opacity) {
super("", true, true, true, true);
this.container = container;
initComponents();
setSize(200, 200);
putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);
scrollPane.setBackground(new Color(0, 0, 0, opacity));
scrollPane.getViewport().setBackground(new Color(0, 0, 0, opacity));
textArea.setBackground(new Color(0, 0, 0, opacity));
setBG();
}
/**
* Builds the GUI
*/
private void initComponents() {
layeredPane = new javax.swing.JLayeredPane();
imageLabel = new javax.swing.JLabel();
scrollPane = new javax.swing.JScrollPane();
textArea = new javax.swing.JTextArea();
imageLabel.setBounds(0, 0, 360, 260);
layeredPane.add(imageLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
scrollPane.setBorder(null);
textArea.setColumns(20);
textArea.setRows(5);
textArea.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
textAreaKeyPressed(evt);
}
public void keyReleased(java.awt.event.KeyEvent evt) {
textAreaKeyReleased(evt);
}
public void keyTyped(java.awt.event.KeyEvent evt) {
textAreaKeyTyped(evt);
}
});
addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentMoved(java.awt.event.ComponentEvent evt) {
frameMoved();
}
public void componentResized(java.awt.event.ComponentEvent evt) {
frameResized();
}
});
scrollPane.setViewportView(textArea);
scrollPane.setBounds(0, 0, 360, 260);
layeredPane.add(scrollPane, javax.swing.JLayeredPane.PALETTE_LAYER);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(layeredPane, javax.swing.GroupLayout.PREFERRED_SIZE, 362, javax.swing.GroupLayout.PREFERRED_SIZE));
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(layeredPane, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE));
}
/**
* The text will be blurred with out this
* @param evt
*/
private void textAreaKeyTyped(java.awt.event.KeyEvent evt) {
repaintAll();
}
/**
* The text will be blurred with out this
* @param evt
*/
private void textAreaKeyPressed(java.awt.event.KeyEvent evt) {
repaintAll();
}
/**
* The text will be blurred with out this
* @param evt
*/
private void textAreaKeyReleased(java.awt.event.KeyEvent evt) {
repaintAll();
}
/**
* Capture whats behind the frame and paint it to the image label
*/
private void setBG() {
setVisible(false);
Rectangle location = new Rectangle(this.getX() + container.getX(),
this.getY() + container.getY(),
(int) this.getSize().getWidth() + 8 + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getWidth(),
(int) this.getSize().getHeight() + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getHeight() + 4);
ImageIcon newIcon = new ImageIcon(createImage((JComponent) container, location));
setVisible(true);
imageLabel.setIcon(newIcon);
repaint();
}
/**
* Only need to update the image label if the frame is moved or resized
*/
private void frameResized() {
setBG();
textArea.repaint();
}
/**
* Only need to update the image label if the frame is moved or resized
*/
private void frameMoved() {
setBG();
for(Component x : container.getComponents())
{
//see if its a jinternalframe
if(x.getClass().getName().equals(this.getClass().getName()))
{
//cast it
TransparentInternalFrame temp = (TransparentInternalFrame)x;
//make sure its not the same one as this
if(x.getBounds().equals(this.getBounds()))
{
return;
}
//if they intersect
if(x.getBounds().intersects(this.getBounds()))
{
this.setVisible(false);
temp.setBG();
this.setVisible(true);
}
}
}
textArea.repaint();
}
private void repaintAll() {
textArea.repaint();
imageLabel.repaint();
layeredPane.repaint();
scrollPane.repaint();
scrollPane.getViewport().repaint();
textArea.repaint();
repaint();
}
/**
* Create a BufferedImage for Swing components.
* All or part of the component can be captured to an image.
*
* @param component Swing component to create image from
* @param region The region of the component to be captured to an image
* @return image the image for the given region
*/
public static BufferedImage createImage(JComponent component, Rectangle region) {
// Make sure the component has a size and has been layed out.
// (necessary check for components not added to a realized frame)
if (!component.isDisplayable()) {
Dimension d = component.getSize();
if (d.width == 0 || d.height == 0) {
d = component.getPreferredSize();
component.setSize(d);
}
layoutComponent(component);
}
BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
// Paint a background for non-opaque components,
// otherwise the background will be black
if (!component.isOpaque()) {
g2d.setColor(component.getBackground());
g2d.fillRect(region.x, region.y, region.width, region.height);
}
g2d.translate(-region.x, -region.y);
component.paint(g2d);
g2d.dispose();
return image;
}
public static void layoutComponent(Component component) {
synchronized (component.getTreeLock()) {
component.doLayout();
if (component instanceof Container) {
for (Component child : ((Container) component).getComponents()) {
layoutComponent(child);
}
}
}
}
private javax.swing.JLabel imageLabel;
private javax.swing.JScrollPane scrollPane;
private javax.swing.JLayeredPane layeredPane;
private javax.swing.JTextArea textArea;
public static void main(String args[])
{
try
{
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
}
catch (Exception e)
{
e.printStackTrace();
}
JFrame container = new JFrame();
container.setSize(800, 800);
JLayeredPane layerPanel = new JLayeredPane();
layerPanel.setSize(800, 800);
container.getContentPane().add(layerPanel);
layerPanel.setVisible(true);
JPanel colorPanel = new JPanel();
colorPanel.setSize(800,800);
colorPanel.setBackground(Color.red);
layerPanel.add(colorPanel);
layerPanel.setLayer(colorPanel, JLayeredPane.DEFAULT_LAYER);
TransparentInternalFrame frameA = new TransparentInternalFrame(layerPanel,0);
frameA.setVisible(true);
layerPanel.add(frameA);
layerPanel.setLayer(frameA, 1);
frameA.setSize(282,282);
TransparentInternalFrame frameB = new TransparentInternalFrame(layerPanel, 0);
frameB.setVisible(true);
layerPanel.add(frameB);
layerPanel.add(frameB,1);
frameB.setLocation(300, 300);
frameB.setSize(282,282);
container.repaint();
container.setVisible(true);
}
}
Puede obtener alguna información de la sección sobre Opacidad en el artículo Pintura en AWT y Swing . En particular, establecer la propiedad opaca no significa, "Hacer que el fondo del componente sea transparente". Una sscce que demuestra el problema también puede ser fructífera.
Adición: Simplificando su ejemplo, parece que el área de texto en sí puede hacerse transparente, pero los valores predeterminados de Nimbus están afectando los límites del área. Puede intentar cambiarlos en consecuencia.
Algunas notas sobre tu código:
- Siempre construya su GUI en el hilo de envío del evento.
- No dibujar desde otro hilo.
- No tragues la excepción.
Adición: ver los cambios para create()
.
Adición: es posible que desee ver también la propiedad isPalette
jif.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JInternalFrame;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;
public class TransparentTextArea extends JTextArea {
int alpha;
public TransparentTextArea(int alpha) {
super(4, 16);
this.alpha = alpha;
this.setBackground(new Color(0, 0, 0, alpha));
this.setFont(new Font("Serif", Font.ITALIC, 24));
this.setEditable(false);
this.setText("Twas brillig and the slithy toves,/n"
+ "Did gyre and gimble in the wabe;/n"
+ "All mimsy were the borogoves,/n"
+ "And the mome raths outgrabe.");
}
private static void create() {
JFrame f = new JFrame();
f.setLayout(new FlowLayout());
f.getContentPane().setBackground(new Color(0xffffc0));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JInternalFrame jif = new JInternalFrame();
JPanel panel = new JPanel();
panel.setBackground(new Color(0xffffc0));
panel.add(new TransparentTextArea(0));
jif.add(panel);
jif.setVisible(true);
f.add(jif);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
create();
}
});
}
}