Как сделать мои JLabels красными с использованием аспекта J?

в моем проекте есть класс MessageUtil, в котором есть методы для отображения сообщений, я пытаюсь сделать тексты моих Jlabels красными, используя аспект J, без использования аспекта J достаточно добавить «цикл for» к одному из методов, которые делают multiLabel текстовое сообщение:

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;
    }

Два метода createMultiLabelByPixel(msg) и createMultiLabelBySlashN(msg) имеют следующую форму:

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

Я хочу использовать аспект J, чтобы сделать JLabels красным, не используя цикл for в теле метода createMultiLabel, я понятия не имею, как это сделать, я пытаюсь создать класс, содержащий аннотацию aspecJ с помощью pointCut ниже, чтобы сделать сообщения массива красными перед отправкой сообщений в createMultiLabelBySlashN() и createMultiLabelByPixel() в качестве их параметра, но я не знаю, правильно ли это или как определить сообщения JLabel [] из метода createMultiLabel в моем аспектеJ class, чтобы сделать его красным, используя тот же цикл for, и отправить результат String в createMultiLabelBySlashN.

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

даже когда я вызываю pointCut, кажется, что в моем коде есть ошибки, которые говорят:

no match for this type name: JLabel

person Community    schedule 28.03.2015    source источник
comment
Мне интересно, достаточно ли ясен этот вопрос. Если вам нужна дополнительная информация, просто спросите   -  person    schedule 28.03.2015


Ответы (1)


no match for this type name: JLabel

Это связано с тем, что вы не используете полное имя класса javax.swing.JLabel.

Теперь предположим, что ваш класс выглядит так (просто подделка):

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;
    }
}

Теперь, если вы запустите метод main без AspectJ, вы увидите следующий вывод консоли:

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]

т.е. все метки имеют серый цвет по умолчанию. Теперь добавьте этот аспект:

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;
    }
}

Аспект изменяет метки, содержащиеся в результирующем массиве, на месте, то есть цикл for теперь находится в вашем коде аспекта, а не в основном коде. Вывод консоли меняется на:

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]

Вуаля — сквозная задача окрашивания этикеток была объединена в отдельный аспект.

person kriegaex    schedule 28.03.2015
comment
спасибо за полный ответ, но возникает вопрос, как работает pointcut без определения полного пути класса createMultiLabel(..)? Я имею в виду путь mehad.util.MessageUtil. - person ; 29.03.2015
comment
Pointcut соответствует любому методу с именем createMultiLabel в любом классе, см. AspectJ Programming Руководство. Это не на 100% точно, но сколько совпадающих имен методов есть в вашей системе? ;-) - person kriegaex; 29.03.2015
comment
только один класс с таким же именем! ;) мой другой вопрос: какой смысл создавать метод multilabelCreation() {}, по какой причине мы не пишем @Around(execution(static javax.swing.JLabel[] createMultiLabel(..))){// changeLabelColours() } напрямую? - person ; 29.03.2015
comment
Вы можете написать pointcut прямо в совете. Использование в возможном повторном использовании, т.е. если у вас есть несколько советов, использующих один и тот же pointcut. Вы также можете комбинировать более простые точки с помощью (комбинаций) && и ||, делая код более читаемым и следуя принципу DRY (не повторяйтесь), избегая избыточности и копирования и вставки. - person kriegaex; 29.03.2015