1

my Project has a MessageUtil class, which has methods to show messages, I'm trying to make the texts of my Jlabels red using aspectJ, without use of aspectJ it is enough to add 'for loop' to one of the methods wich makes multiLabel text message:

public static JLabel[] createMultiLabel(String msg) {

        JLabel[] messages = null;
        if (msg.contains("\n")) {
        messages =  createMultiLabelBySlashN(msg);
        } else {
            messages = createMultiLabelByPixel(msg);
        }
        //this for loop makes the text red
        for (int i = 0; i < messages.length; i++) {
            messages[i].setForeground(Color.RED);
        }
        return messages;
    }

The two methods createMultiLabelByPixel(msg) and createMultiLabelBySlashN(msg) are in this form:

private static JLabel[] createMultiLabelBySlashN(String msg) { 
// the code here 
}

I want to use aspectJ inorder to make the JLabels red, not using the for loop in the body of method createMultiLabel,I don't have any idea how to do this, I'm trying to make a class containing aspecJ annotation with the pointCut below to make the array messages red before the messages is sent to createMultiLabelBySlashN() and createMultiLabelByPixel() as their parameter, but I don't know if it is correct or how to define the JLabel messages[] from the method createMultiLabel in my aspectJ class to make it red using the same for loop and send the String rezult to createMultiLabelBySlashN.

@Pointcut ("execution(public static JLabel[] mehad.util.MessageUtil.createMultiLabelBySlashN(..)) || execution(public static JLabel[] mehad.util.MessageUtil.createMultiLabelByPixel(..)" )

even when I'm calling the pointCut it seems there are errors with my code that says:

no match for this type name: JLabel
  • I'm wondering if this question is clear enough. If you need more information just ask –  Mar 28 '15 at 10:33

1 Answers1

0

no match for this type name: JLabel

This is because you do not use the fully qualified class name javax.swing.JLabel.

Now let us assume your class looks like this (just a simple fake):

package mehad.util;

import javax.swing.JLabel;

public class MessageUtil {
    public static void main(String[] args) {
        for (JLabel label : createMultiLabel("Albert Einstein\nWerner Heisenberg\nMax Planck"))
            System.out.println(label.getText() + " / " + label.getForeground());
        System.out.println();
        for (JLabel label : createMultiLabel("Albert Einstein, Werner Heisenberg, Max Planck"))
            System.out.println(label.getText() + " / " + label.getForeground());
    }

    public static JLabel[] createMultiLabel(String msg) {
        return msg.contains("\n")
            ? createMultiLabelBySlashN(msg)
            : createMultiLabelByPixel(msg);
    }

    private static JLabel[] createMultiLabelBySlashN(String msg) {
        String[] lines = msg.split("\n+");
        JLabel[] labels = new JLabel[lines.length];
        for (int i = 0; i < lines.length; i++)
            labels[i] = new JLabel(lines[i]);
        return labels;
    }

    private static JLabel[] createMultiLabelByPixel(String msg) {
        String[] words = msg.split("[, ]+");
        JLabel[] labels = new JLabel[words.length];
        for (int i = 0; i < words.length; i++)
            labels[i] = new JLabel(words[i]);
        return labels;
    }
}

Now if you run the main method without AspectJ, you will see this console output:

Albert Einstein / sun.swing.PrintColorUIResource[r=51,g=51,b=51]
Werner Heisenberg / sun.swing.PrintColorUIResource[r=51,g=51,b=51]
Max Planck / sun.swing.PrintColorUIResource[r=51,g=51,b=51]

Albert / sun.swing.PrintColorUIResource[r=51,g=51,b=51]
Einstein / sun.swing.PrintColorUIResource[r=51,g=51,b=51]
Werner / sun.swing.PrintColorUIResource[r=51,g=51,b=51]
Heisenberg / sun.swing.PrintColorUIResource[r=51,g=51,b=51]
Max / sun.swing.PrintColorUIResource[r=51,g=51,b=51]
Planck / sun.swing.PrintColorUIResource[r=51,g=51,b=51]

I.e. all labels have a default grey colour. Now add this aspect:

package de.scrum_master.aspect;

import java.awt.Color;

import javax.swing.JLabel;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class RedLabelAspect {
    @Pointcut("execution(static javax.swing.JLabel[] createMultiLabel(..))")
    public void multilabelCreation() {}

    @Around("multilabelCreation()")
    public JLabel[] changeLabelColours(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        JLabel[] labels = (JLabel[]) thisJoinPoint.proceed();
        for (JLabel label : labels)
            label.setForeground(Color.RED);
        return labels;
    }
}

The aspect modifies the labels contained in the result array in place, i.e. the for loop now resides in your aspect code, no longer in the core code. The console output changes to:

Albert Einstein / java.awt.Color[r=255,g=0,b=0]
Werner Heisenberg / java.awt.Color[r=255,g=0,b=0]
Max Planck / java.awt.Color[r=255,g=0,b=0]

Albert / java.awt.Color[r=255,g=0,b=0]
Einstein / java.awt.Color[r=255,g=0,b=0]
Werner / java.awt.Color[r=255,g=0,b=0]
Heisenberg / java.awt.Color[r=255,g=0,b=0]
Max / java.awt.Color[r=255,g=0,b=0]
Planck / java.awt.Color[r=255,g=0,b=0]

Voilà - the cross-cutting concern of colouring the labels has been modularised into an aspect.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • thanks for the complete answer, but it arouse a question, how the pointcut works without defining the complete path of class createMultiLabel(..)? I mean the path mehad.util.MessageUtil. –  Mar 29 '15 at 06:55
  • The pointcut matches any method named `createMultiLabel` in any class, see [AspectJ Programming Guide](https://eclipse.org/aspectj/doc/next/progguide/semantics-pointcuts.html#matching). It is not 100% exact, but how many matching method names do you have in your system? `;-)` – kriegaex Mar 29 '15 at 09:20
  • just one class with the same name! ;) my other question is what's the use of making a method multilabelCreation() {}, what's the reason we don't write @Around("execution(static javax.swing.JLabel[] createMultiLabel(..))"){// changeLabelColours() } directly? –  Mar 29 '15 at 10:31
  • You can write the pointcut directly in the advice. The use is in possible re-use, i.e. if you have multiple advice using the same pointcut. You can also combine simpler pointcuts via (combinations of) `&&` and `||`, making the code more readably and following the DRY (don't repeat yourself) principle by avoiding redundancy and copy'n'paste. – kriegaex Mar 29 '15 at 10:37